Reputation: 772
Here is a Row
, which is inside ListView
. Inside it's a Column
with Text
widgets, leading and trailing widgets. The problem is that the leading widget has to fill the free height of the Row
. The Row
height is determined by the Column
with the Text
widgets, and the leading widget should adjust to this size and not try to increase the Row
height to infinity (for example, the leading widget can be a colored Container
with infinite height and given width). Is it possible to do this?
Upvotes: 14
Views: 21052
Reputation: 8383
Use crossAxisAlignment: CrossAxisAlignment.stretch
to fill the height
of a Row
(width
of a Column
), i.e. to stretch along the CrossAxis.
Use Expanded
widgets to fill the space along the MainAxis The flex attributes will determine the proportion of each widget.
For the trailing widget, just use a Center
widget to center it.
In order to have your Row
inside a ListView
, stretching to the height of the tallest child, put the Row
inside an IntrinsicHeight
widget.
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Row and Column',
home: Scaffold(
body: ListView(
children: [
IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(child: MyWidget()),
Expanded(
flex: 3,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
MyTextWidget(
text:
'I like to believe that science is becoming mainstream.',
),
MyTextWidget(
text:
'There is no known objects accounting for most of the effective gravity in the universe.',
),
MyTextWidget(
text: "Let's explore because it's fun.",
),
],
),
),
Expanded(
child: Center(
child: SizedBox(height: 40.0, child: MyWidget()),
),
),
],
),
),
Spacer(),
],
),
),
),
);
}
class MyTextWidget extends StatelessWidget {
final String text;
const MyTextWidget({Key key, this.text}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
padding: const EdgeInsets.all(4.0),
color: Colors.blueGrey,
child: Text(text),
),
);
}
}
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(color: Colors.blueGrey),
);
}
}
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Row and Column',
home: Scaffold(
body: ListView(
children: [
IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(child: MyWidget()),
Expanded(
flex: 3,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
MyTextWidget(
text:
'I like to believe that science is becoming mainstream.',
),
MyTextWidget(
text:
'There is no known objects accounting for most of the effective gravity in the universe.',
),
MyTextWidget(
text: "Let's explore because it's fun.",
),
],
),
),
Expanded(
child: Center(
child: SizedBox(height: 40.0, child: MyWidget()),
),
),
],
),
),
Spacer(),
],
),
),
),
);
}
class MyTextWidget extends StatelessWidget {
final String text;
const MyTextWidget({Key key, this.text}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
padding: const EdgeInsets.all(4.0),
color: Colors.blueGrey,
child: Text(text),
),
);
}
}
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(color: Colors.blueGrey),
);
}
}
Upvotes: 28
Reputation: 3288
@Thierry's answer is good. But if your row has dynamic height (for example your subtitles have undefined length and row should expand height that depends on it) then you can use Stack
widget as root widget of your list item to handle this. Here is working code:
@override
Widget build(BuildContext context) {
final leadingWidgetWidth = 120.0;
return Stack(children: [
Positioned.fill(
child: Container(
alignment: Alignment.centerLeft,
// This child will fill full height, replace it with your leading widget
child: Container(
color: Colors.blue,
width: leadingWidgetWidth,
),
),
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(width: leadingWidgetWidth),
Expanded(
// Here your column with texts
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text('Title'),
Text('Some dynamic text'),
Text('Some dynamic text'),
],
),
),
Expanded(
// Here your trailing widget
child: Container(color: Colors.blueGrey),
)
],
)
]);
}
Upvotes: 17
Reputation: 206
if you want them to have a maximum size of the main-axis you can add an attribute
mainAxisSize: MainAxisSize.max
if you want it to be minimum size, then use MainAxisSize.min
instead (works on Row and Column)
if you want to make a cross-axis on max size, then you can add SizedBox before them and then add height or width with double.infinity
like this height: double.infinity
Upvotes: 2