Is it possible to make a GridView.builder that takes the height of its children, instead of specifying a certain height on its parent?
I have a GridView.builder that is supposed to put the content of a list. I get an error because I didn't specify height on the parent container, but I would like the GridView to take only the minimal necessary height so the children fit.
This is my GridView:
return SizedBox(
// height: 400,
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: MediaQuery.of(ctx).size.width /
(MediaQuery.of(ctx).size.height / 4),
crossAxisCount: MediaQuery
.of(ctx)
.size
.width > 600 ? 3 : 1,
),
itemCount: content.length,
itemBuilder: (BuildContext ctx, index) {
return SizedBox(
height: 100,
width: 300,
child: ListTile(
leading: content[index]["icon"],
title: content[index]["title"],
subtitle: Expanded(
child: Text(
content[index]["text"],
style: const TextStyle(fontSize: 18),
),
),
),
);
},
),
);
The list is something like this:
List content = [
{"icon": ...,
"title": ...,
"text": ...},
{"icon": ...,
"title": ...,
"text": ...},
{"icon": ...,
"title": ...,
"text": ...},
{"icon": ...,
"title": ...,
"text": ...},
];
And these are some of the errors that appear on my console:
This is what I get if I remove the SizeBox wrapping the GridView:
Note how index 0 has size but on index 1 it is missing. I don't know what that means.
Could somebody help me? My doubt is pretty basic but I attached my code in case I am the one doing something wrong which is very specific.
Thank you in advance.
CodePudding user response:
Yes it is possible with minHeight & maxHeight property inside BoxConstraints... The errors you facing because of not mentioned width and height property for your Parent Widget. It is necessary to define width and height property for ListView or GridView... instead of using SizedBox change it to Container... then in constraints property you can define your sizes. For good code standard always use Min/Max width and height
Example code :
Container(
constraints: BoxConstraints( //below mentioned sizes for reference only
minWidth: 100.0,
maxWidth: 320.0,
minHeight: 100.0,
maxHeight: 600.0),
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: MediaQuery.of(ctx).size.width /
(MediaQuery.of(ctx).size.height / 4),
crossAxisCount: MediaQuery
.of(ctx)
.size
.width > 600 ? 3 : 1,
),
itemCount: content.length,
itemBuilder: (BuildContext ctx, index) {
return SizedBox(
height: 100,
width: 300,
child: ListTile(
leading: content[index]["icon"],
title: content[index]["title"],
subtitle: Expanded(
child: Text(
content[index]["text"],
style: const TextStyle(fontSize: 18),
),
),
),
);
},
),
);
CodePudding user response:
Maybe you could wrap it inside a column and use flexible or expanded widgets to set the proportion for the GridView and other childs.
Column(
children: [
Flexible(
flex: 1,
child: SizedBox(
// height: 400,
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: MediaQuery.of(ctx).size.width /
(MediaQuery.of(ctx).size.height / 4),
crossAxisCount:
MediaQuery.of(ctx).size.width > 600 ? 3 : 1,
),
itemCount: content.length,
itemBuilder: (BuildContext ctx, index) {
return SizedBox(
height: 100,
width: 300,
child: ListTile(
leading: content[index]["icon"],
title: content[index]["title"],
subtitle: Expanded(
child: Text(
content[index]["text"],
style: const TextStyle(fontSize: 18),
),
),
),
);
},
),
),
),//Other childs
Flexible(
flex: 3,
child: SizedBox(
child: Container(
color: Colors.red,
),
),
)
],
),