Repository navigation
Change height of GridView row to fixed height #55290
Copy link
Copy link
Closed
Labels
P3Issues that are less important to the Flutter projectIssues that are less important to the Flutter projectc: new featureNothing broken; request for a new capabilityNothing broken; request for a new capabilityf: scrollingViewports, list views, slivers, etc.Viewports, list views, slivers, etc.frameworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.team-frameworkOwned by Framework teamOwned by Framework teamtriaged-frameworkTriaged by Framework teamTriaged by Framework teamworkaround availableThere is a workaround available to overcome the issueThere is a workaround available to overcome the issue
Description
I've noticed that GridView makes each child a square.. I know we can change dynamically height of grid view row by setting childAspectRatio. That however doesn't make it fixed so when the device rotate then the height changed as well
In this example I want to have each input next to each other and keep it's height same on all devices and all display orientation. (nobody wants their text input change its height)
List<Map<String, dynamic>> list = [
{'description': 'des1'},
{'description': 'des2'},
{'description': 'des3'},
{'description': 'des4'},
{'description': 'des5'},
{'description': 'des6'}
];
class _MaterialScreenState extends State<MaterialScreen> {
String text = '';
@override
Widget build(BuildContext context) {
double height = MediaQuery.of(context).size.height;
double width = MediaQuery.of(context).size.width;
return Scaffold(
body: Column(
children: <Widget>[
Text(text),
GridView.builder(
shrinkWrap: true,
itemCount: list.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 5,
crossAxisSpacing: 5,
mainAxisSpacing: 5,
childAspectRatio: width / (height / 4)),
itemBuilder: (BuildContext context, int index) {
return TextFormField(
textAlign: TextAlign.center,
onTap: () => setState(() {
text = list[index]['description'];
}),
decoration: InputDecoration(
border: OutlineInputBorder(),
//isDense: true,
contentPadding: EdgeInsets.all(8)),
);
}),
],
))
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
P3Issues that are less important to the Flutter projectIssues that are less important to the Flutter projectc: new featureNothing broken; request for a new capabilityNothing broken; request for a new capabilityf: scrollingViewports, list views, slivers, etc.Viewports, list views, slivers, etc.frameworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.team-frameworkOwned by Framework teamOwned by Framework teamtriaged-frameworkTriaged by Framework teamTriaged by Framework teamworkaround availableThere is a workaround available to overcome the issueThere is a workaround available to overcome the issue
Activity
VladyslavBondarenko commentedon Apr 21, 2020
Related to #13777, #29035
perfoWorks commentedon Apr 21, 2020
@VladyslavBondarenko Yes but they all managed to fixed it by setting childAspectRatio.. In my case I can't really do it unless I give up fixed number of items and use maxCrossAxisExtent: which I don't want. I just want the rows to be fixed size and with certain number of items
Zannier7 commentedon Oct 2, 2020
aspect ratio does not work for all mobile screen sizes 👎 .
elMuso commentedon Oct 3, 2020
Hey. Since flutter is open source you can just track the delegate and extend it to use a fixed height. And you can make a custom Delegate !
As an example, i made SliverGridDelegateWithFixedCrossAxisCountAndFixedHeight in which the aspectratio is ignored, and the fixed height is forced.
to use it simply do
jntagadiad commentedon Oct 15, 2020
thanks a lot!
NanobyteRuata commentedon Oct 17, 2020
I made a workaround like
At least in my case, I needed maxWidth but not maxHeight because my Container height depended on it's child contents and I liked it that way.
I used asMap().map() because I wanted to get the index
You can make it more simple using just map()
To scroll u can wrap the Wrap with SingleChildScrollView
jamesdixon commentedon Feb 8, 2021
@ayRatul YES! Nice work and thank you
trailerzone commentedon Apr 14, 2021
Thanks! I was trying to find a solution all of yesterday and this morning I finally found your solution and modified it. Works perfectly! I added SingleChildScrollView to a container above it so I can scroll. We could make a widget for others who are struggling with this or flutter could add this to their core! :)
atn832 commentedon May 22, 2021
How about using
mainAxisExtentinstead ofchildAspectRatio? Then the code becomes:https://api.flutter.dev/flutter/rendering/SliverGridDelegateWithMaxCrossAxisExtent/mainAxisExtent.html
https://api.flutter.dev/flutter/rendering/SliverGridDelegateWithFixedCrossAxisCount/mainAxisExtent.html
kamleshwebtech commentedon May 25, 2021
Getting error "A RenderFlex overflowed by 74 pixels on the bottom." Thanks.
mahmedMostafa commentedon May 28, 2021
aspect ratio is the worst
ShaheryarMalik007 commentedon Sep 16, 2021
Taking @elMuso 's answer as a reference
if someone wants to use the Max Cross Axis Extenet along with fixed height, this might be useful for responsiveness
class SliverGridDelegateWithMaxCrossAxisExtentAndFixedHeight
extends SliverGridDelegate {
/// Creates a delegate that makes grid layouts with a fixed number of tiles in
/// the cross axis.
///
/// All of the arguments must not be null. The
mainAxisSpacingand///
crossAxisSpacingarguments must not be negative. ThecrossAxisCount/// and
childAspectRatioarguments must be greater than zero.// const SliverGridDelegateWithFixedCrossAxisCountAndFixedHeight({
const SliverGridDelegateWithMaxCrossAxisExtentAndFixedHeight(
{
this.crossAxisExtent=0.0,
required this.maxCrossAxisExtent,
this.mainAxisSpacing = 0.0,
this.crossAxisSpacing = 0.0,
this.mainAxisExtent,
this.height = 56.0,
}) :
//assert(crossAxisCount != null && crossAxisCount > 0),
assert(mainAxisSpacing != null && mainAxisSpacing >= 0),
assert(crossAxisSpacing != null && crossAxisSpacing >= 0),
assert(height != null && height > 0);
/// The number of children in the cross axis.
// final int crossAxisCount;
/// The number of logical pixels between each child along the main axis.
final double mainAxisSpacing;
/// The number of logical pixels between each child along the cross axis.
final double crossAxisSpacing;
/// The height of the crossAxis.
final double height;
/// For example, if the grid is vertical, the grid is 500.0 pixels wide, and
/// [maxCrossAxisExtent] is 150.0, this delegate will create a grid with 4
/// columns that are 125.0 pixels wide.
final double maxCrossAxisExtent;
final double crossAxisExtent;
/// If null, [childAspectRatio] is used instead.
final double? mainAxisExtent;
/// The ratio of the cross-axis to the main-axis extent of each child.
// final double childAspectRatio;
bool _debugAssertIsValid(double crossAxisExtent) {
// assert(crossAxisCount > 0);
}
@OverRide
SliverGridLayout getLayout(SliverConstraints constraints) {
assert(_debugAssertIsValid(constraints.crossAxisExtent));
}
@OverRide
bool shouldRelayout(
SliverGridDelegateWithMinCrossAxisExtentAndFixedHeight oldDelegate) {
return
// oldDelegate.crossAxisCount != crossAxisCount ||
oldDelegate.crossAxisExtent!=crossAxisExtent||
oldDelegate.crossAxisExtent!=crossAxisExtent||
oldDelegate.mainAxisSpacing != mainAxisSpacing ||
oldDelegate.crossAxisSpacing != crossAxisSpacing ||
oldDelegate.height != height;
}
}
8 remaining items
emaborsa commentedon Sep 1, 2023
I used this sample as well, but I have the problem that the container get stretched by the
GridView.Here my code:
If instead of the
GridViewi use another container suchText, the cell is not stretched.Any hint?
rohandevo commentedon Feb 13, 2025
I guess, rather using child aspect ratio, Let child handle the height and width of the container in the grid view. Remove the child aspect ratio. My problems here is, Whenever I make grid. Giving child aspect ratio doesn't help. As if height of smartphone becomes lower the container start spreading more which shouldn't happen. Also if I forcefully make container smaller, It leaves a gap between the container vertically. Just remove the child aspect ratio and let child handle the height and width of the container.
This this helps but still vertically gap between container spread ->
class SliverGridDelegateWithFixedCrossAxisCountAndFixedHeight
extends SliverGridDelegate {
/// Creates a delegate that makes grid layouts with a fixed number of tiles in
/// the cross axis.
///
/// All of the arguments must not be null. The
mainAxisSpacingand///
crossAxisSpacingarguments must not be negative. ThecrossAxisCount/// and
childAspectRatioarguments must be greater than zero.const SliverGridDelegateWithFixedCrossAxisCountAndFixedHeight({
@required this.crossAxisCount,
this.mainAxisSpacing = 0.0,
this.crossAxisSpacing = 0.0,
this.height = 56.0,
}) : assert(crossAxisCount != null && crossAxisCount > 0),
assert(mainAxisSpacing != null && mainAxisSpacing >= 0),
assert(crossAxisSpacing != null && crossAxisSpacing >= 0),
assert(height != null && height > 0);
/// The number of children in the cross axis.
final int crossAxisCount;
/// The number of logical pixels between each child along the main axis.
final double mainAxisSpacing;
/// The number of logical pixels between each child along the cross axis.
final double crossAxisSpacing;
/// The height of the crossAxis.
final double height;
bool _debugAssertIsValid() {
assert(crossAxisCount > 0);
assert(mainAxisSpacing >= 0.0);
assert(crossAxisSpacing >= 0.0);
assert(height > 0.0);
return true;
}
@OverRide
SliverGridLayout getLayout(SliverConstraints constraints) {
assert(_debugAssertIsValid());
final double usableCrossAxisExtent =
constraints.crossAxisExtent - crossAxisSpacing * (crossAxisCount - 1);
final double childCrossAxisExtent = usableCrossAxisExtent / crossAxisCount;
final double childMainAxisExtent = height;
return SliverGridRegularTileLayout(
crossAxisCount: crossAxisCount,
mainAxisStride: childMainAxisExtent + mainAxisSpacing,
crossAxisStride: childCrossAxisExtent + crossAxisSpacing,
childMainAxisExtent: childMainAxisExtent,
childCrossAxisExtent: childCrossAxisExtent,
reverseCrossAxis: axisDirectionIsReversed(constraints.crossAxisDirection),
);
}
@OverRide
bool shouldRelayout(
SliverGridDelegateWithFixedCrossAxisCountAndFixedHeight oldDelegate) {
return oldDelegate.crossAxisCount != crossAxisCount ||
oldDelegate.mainAxisSpacing != mainAxisSpacing ||
oldDelegate.crossAxisSpacing != crossAxisSpacing ||
oldDelegate.height != height;
}
}
feat: Add `mainAxisExtent` parameter to `GridView` constructors
feat: Add `mainAxisExtent` parameter to `GridView` constructors
feat: Add `mainAxisExtent` parameter to `GridView` constructors
feat: Add `mainAxisExtent` parameter to `GridView` constructors
feat: Add `mainAxisExtent` parameter to `GridView` constructors
feat: Add `mainAxisExtent` parameter to `GridView` constructors
feat: Add `mainAxisExtent` parameter to `GridView` constructors
feat: Add `mainAxisExtent` parameter to `GridView` constructors (#176927
feat: Add `mainAxisExtent` parameter to `GridView` constructors (flut…
github-actions commentedon Dec 17, 2025
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.