'Flutter: Get ListView size to create dynamic item sizes
I'm trying to create a ListView in Flutter where the total sum of its items' width is the width of the ListView itself.
In other words: I have 24 items, and I want each one to have an extent of [ListView.width]/24. However, I cannot seem to get the width of the list view inside of its builder.
I tried using context.size.width:
itemBuilder: (context, i) {
return Container(
width: context.size.width,
//And so on....
but I get the following error:
Cannot get size during build.
I also tried using Extended at each of the item's root, but it predictably didn't work.
Is there any way to obtain the width of the item's parent (the list view) and use it to calculate its extent dynamically?
Thanks.
Solution 1:[1]
If you're trying to get the ListView
to display some items horizontally across the widget, put the children inside a Row
and wrap each with an Expanded
:
ListView.builder(
itemCount: 1,
itemBuilder: (_, i) => Row(
children: [
Expanded(child: Container(height: 50, color: Colors.red)),
Expanded(child: Container(height: 50, color: Colors.blue)),
Expanded(child: Container(height: 50, color: Colors.red)),
Expanded(child: Container(height: 50, color: Colors.blue)),
Expanded(child: Container(height: 50, color: Colors.red)),
Expanded(child: Container(height: 50, color: Colors.blue)),
Expanded(child: Container(height: 50, color: Colors.red)),
Expanded(child: Container(height: 50, color: Colors.blue)),
Expanded(child: Container(height: 50, color: Colors.red)),
Expanded(child: Container(height: 50, color: Colors.blue)),
Expanded(child: Container(height: 50, color: Colors.red)),
Expanded(child: Container(height: 50, color: Colors.blue)),
Expanded(child: Container(height: 50, color: Colors.red)),
Expanded(child: Container(height: 50, color: Colors.blue)),
Expanded(child: Container(height: 50, color: Colors.red)),
Expanded(child: Container(height: 50, color: Colors.blue)),
Expanded(child: Container(height: 50, color: Colors.red)),
Expanded(child: Container(height: 50, color: Colors.blue)),
Expanded(child: Container(height: 50, color: Colors.red)),
Expanded(child: Container(height: 50, color: Colors.blue)),
],
),
),
If you're trying to do this with a ListView
in a horizontal orientation, then I would recommend to not use a ListView
at all. Just use the Row
in the first place.
EDIT: Since this answer was made, Dart has released a version that allows loops in list definitions. As such, a more proper way to do the above would be this:
ListView.builder(
itemCount: 1,
itemBuilder: (_, i) => Row(
children: [
for (int j = 0; j < 20; j++)
Expanded(
child: Container(
height: 50,
color: j.isEven ? Colors.blue : Colors.red,
),
),
],
),
),
Solution 2:[2]
ScheduleBinding.instance.addPostFrameCallback((duration) {
RenderBox box = _keyOfTheWidget.currentContext.getRenderObject();
// For size of wiget
Size size = box.size;
// For position
Offset offset = box.localToGlobal(Offset.zero);
setState(() => newSize = size);
});
Use this method... its postFrameCallback that happens once the widget is rendered.. you can get the size of the widget and then repaint the widget to be in your desired size.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Jerin |