Gridview.count
inside Column
and wrapped by SingleChildScrollView
crops button
text
due to shrinkWrap: true
. Without shrinkWrap: true
, flutter throws an error, shown bellow.
I’ve already tried changing physics: BouncingScrollPhysics()
property to NeverScrollableScrollPhysics()
inside Gridview.count
but it throws the same error:
The following assertion was thrown during performResize():
Vertical viewport was given unbounded height.
Viewports expand in the scrolling direction to fill their container. In this case, a vertical
viewport was given an unlimited amount of vertical space in which to expand. This situation
typically happens when a scrollable widget is nested inside another scrollable widget.
If this widget is always nested in a scrollable widget there is no need to use a viewport because
there will always be enough vertical space for the children. In this case, consider using a Column
or Wrap instead. Otherwise, consider using a CustomScrollView to concatenate arbitrary slivers into
a single scrollable.
It’s pretty self-explanatory, but I’ve already tried creating a layout with rows and columns, but I cannot make them to get the same height and width of the biggest choice button (which is what I want). That’s why I tried using Gridview.count
.
Obs.: Of course, I cannot give a fixed height to the Column because the text size inside the buttons is variable.
Here is the code snippet (look how text choice 4 is cropped):
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorSchemeSeed: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
const MyHomePage({
super.key,
required this.title,
});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final _controller = ScrollController();
List<Widget> choiceButtons = [
OutlinedButton(
onPressed: () {},
child: Text('choice 1: this size this size this size'),
),
OutlinedButton(
onPressed: () {},
child: Text(
'choice 2: this size this size this size this size this size this size'),
),
OutlinedButton(
onPressed: () {},
child: Text('choice 3: this size'),
),
OutlinedButton(
onPressed: () {},
child: Text(
'choice 4: this size this size this size this size this size this size this size this size this size this size this size '),
),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: SafeArea(
child: Scrollbar(
child: SingleChildScrollView(
controller: _controller,
child: SizedBox(
width: 400,
child: Column(
children: [
Text('test'),
Center(
child: GridView.count(
physics: BouncingScrollPhysics(),
scrollDirection: Axis.vertical,
shrinkWrap: true,
crossAxisCount: 2,
childAspectRatio: 1 / .4,
mainAxisSpacing: 2,
children: List.generate(choiceButtons.length, (index) {
return Padding(
padding: const EdgeInsets.all(10.0),
child: choiceButtons[index],
);
}),
),
),
Text('test'),
],
),
),
),
),
),
);
}
}
What could I do?
2
Answers
You probably have to manually layout children in the render layer in this case.
Or use
Boxy
library if you want to reduce some boilerplateJust remove childAspectRatio: 1 / .4, and its working.