Flutter: How to fix "A RenderFlex overflowed by pixels " error?
try to use Expanded instead of Container in _buildImageBoxes() function
Widget _buildImageBoxes() {
return Column(
children: <Widget>[
Expanded(
child: Image.network("https://picsum.photos/500/500/?random"),
),
Container(
padding: EdgeInsets.all(10),
child: Text("Text"),
)
],
);
}
Expanded
→ Calculated Space
Expanded
or Flexible
widgets in Column
or Row
will make Flutter calculate remaining space & use that space for layout.
Widgets not in Expanded
or Flexible
are laid out regardless of screen/constraint space.
Why / How this works
Column
and Row
are laid out in two main phases:
- non-
Flexible
items Flexible
items (Expanded
andFlexible
widgets)
Phase 1
Flutter does Phase 1 without screen size or any other constraint in mind.
Flutter just adds all non-flex-factor item sizes together.
Sum too big for screen or other constraint? → RenderFlex overflowed
exception.
Phase 2
Widgets with flex
constructor argument are flex-factor items.
i.e. Flexible
or Expanded
widgets. (Spacer
too, but no one uses it.)
After Phase 1, any flex-factor widgets are laid out with remaining space in mind.
Key difference between non-flexible and flex-factor layout phases:
- non-flex layout → regardless of space
- flex-factor layout → uses remaining space
Inside Column
or Row
, wrapping widgets in Expanded
or Flexible
, Flutter will calculate remaining space for their layout. This would prevent a RenderFlex overflowed
exception in the question since each Image
widget will size itself to space constraints.
But during Phase 1, there are no space constraints. So the Images
aren't resized (and overflow).
Children widgets inside Column
or Row
not wrapped in Expanded
or Flexible
will be laid out at their intrinsic size, regardless of screen/constraint space.
Before
Space 400
Column
Image 150
Image 150
Image 150
Sum non-flex Images: 450. Space available: 400 → Overflowed
Solution: use Phase 2 → use calculated space
After
Wrapping Image
in flex widget Expanded
, height available is calculated then shared among Expanded
(as constraints) and Image
is resized to fit inside Expanded
constraints:
Space 400
Column
Expanded 133
→ Image ←
Expanded 133
→ Image ←
Expanded 133
→ Image ←
Sum flex Expandeds: 399. Space: 400 → OK
Widget build(BuildContext context) {
final _screenSize = MediaQuery.of(context).size;
return Container(
height: _screenSize.height * 0.2,);
}
MediaQuery.of(context)
It worked for me to use!