How to make children of a Row have the same height by reading child constraints
This can be done cleverly using Stack
instead, because the size of the Stack
will match its non-positioned children, so it will automatically match your Text
widget. Then use a Positioned
widget to display the image - set both its top
and bottom
to 0
to make it stretch vertically, set right: 0
to make it align, and give it a fixed width.
Sample source code:
class Test extends StatelessWidget {
const Test({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Flutter Demo")),
body: ListView(
children: [
for (int i = 8; i < 40; i += 6)
Stack(
children: [
Padding(
padding: EdgeInsets.only(right: 100),
child: Text("Lorem ipsum " * i),
),
Positioned(
top: 0,
bottom: 0,
right: 0,
width: 100,
child: Container(color: Colors.primaries[i % 10]),
),
],
),
],
),
);
}
}
Update:
You mentioned in the comments, you would want to enforce a "minimum height". You can easily do that in the Stack
, by putting an invisible SizedBox
, for example:
Stack(
children: [
Padding(
padding: EdgeInsets.only(right: 100),
child: Text("Lorem ipsum " * i),
),
SizedBox(height: 100), // this forces minimum height
Positioned(
top: 0,
bottom: 0,
right: 0,
width: 100,
child: Container(color: Colors.primaries[i % 10]),
),
],
),
Result:
shadysamir
Updated on January 01, 2023Comments
-
shadysamir over 1 year
I have a SliverList with a delegate that returns Row for each item. The design requires this result:
The two children are Text and Image. The Image fir is BoxFit.cover and I am using Flexible to give them the desired width ratio. I need the image boundary height to match the text height only if the height is greater than or equal to width boundary (to keep it at least a square).
First solution was to use LayoutBuilder to read the constraints of the image width and put the image in a ConstrainedBox with minHeight of LayoutBuilder->constraints->maxWidth.
LayoutBuilder( builder: (context, constraints) => ConstrainedBox( constraints: BoxConstraints( minHeight: constraints.maxWidth, maxHeight: constraints.maxWidth), child: CachedNetworkImage( imageUrl: "https://via.placeholder.com/400x300", fit: BoxFit.cover, ), ), )
All is well until the text is longer than image width, at this point the image remains a square and does not stretch to the full row height:
Second solution was to wrap the Row in an IntrinsicHeight widget. But this means I can't use the LayoutBuilder inside it. So I removed the Layout builder and now I can't access the constraints to set the Image minHeight. The Image stretches very well to fill the full Row height. Until when the text is too short, which makes the image height go below its width:
How can I build this design to be responsive with variable text height?
-
shadysamir over 2 yearsI already achieved this (see solution 2 in my question). The problem is to keep the container of both text and image at a minimum height of what the image width is right now so that the image is at least a square if not tall (first image in required design)
-
WSBT over 2 years@shadysamir Your "solution 2" uses IntrinsicHeight which will cause flutter to layout twice, inefficient. To enforce a "minimum height" you can simply add another
SizedBox
in theStack
, see my updated answer. -
shadysamir over 2 yearsYou sent me in the right direction. Your answer was almost there. What was missing was responsiveness. Width available for image is not necessarily 100. I will write the answer I reached that solved it for me.