[Flutter/dart] Resize the widget to fit the area left in the Column or Row
Overview
When making an app with Flutter, there is a situation where "I want to place a widget of a certain size and maximize the other widget to fit the remaining space".
For example, you might place an ad at the bottom of the page and scroll the elements in the remaining area with a SingleChildScrollView.
We will summarize the measures to be taken in such cases.
Method
Use Expanded or Flexible.
Both of them change the size of the child widget according to the area of Row and Column excluding the widgets that have other fixed sizes.
In the example below, Expanded reserves the height excluding the height of the SizedBox, and if the Column does not fit within it, it can be scrolled and displayed.
@override
Widget build(BuildContext context) {
List<int> list=List.generate(20, (index) => index);
return Scaffold(
appBar: AppBar(
title: Text('demo'),
),
body: Container(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded( //ここ
child: SingleChildScrollView(
child: Column(
children: list.map((e) =>
ListTile(
title: Text(
e.toString(),
style: TextStyle(
fontSize: 18
),
),
)
).toList(),
),
)
),
SizedBox(
height: 80,
child: Container(
color: Colors.red,
),
),
],
)
)
);
}
Expanded maximizes the child widget to fit the size of the remaining area, while Flexible optimizes the size to fit the size of the child widget in the remaining area.
For example, consider placing an icon image, a character string, and a time in a Row, with placing an icon and a time first and placing string in the remaining area. In this case, if Expanded is used, and if the character string is short, there will be an unnatural gap between the character string and the time.
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('demo'),
),
body: Container(
padding: const EdgeInsets.all(16),
child: Row(
children: [
Icon(Icons.brightness_1),
Expanded( //here
child: Text(
"abc",
style: TextStyle(
fontSize: 18
),
),
),
Text(
'19:00',
style: TextStyle(
fontSize: 18
),
)
],
)
)
);
}
Flexible allows you to place the time just after the string.
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('demo'),
),
body: Container(
padding: const EdgeInsets.all(16),
child: Row(
children: [
Icon(Icons.brightness_1),
Flexible( //here
child: Text(
"abc",
style: TextStyle(
fontSize: 18
),
),
),
Text(
'19:00',
style: TextStyle(
fontSize: 18
),
)
],
)
)
);
}
By the way, without Expanded or Flexible, if the character string is long, it will be "RenderFlex overflowed ..." exception. You can't avoid this just setting the overflow property on Text.
Summary
In the remaining area
・Maximize child widget → Expanded
・Variable according to the size of the child widget → Flexible
Recent Posts
See AllWhat want to do I want to create an input form using TextField. For example, if the input content is a monetary amount, I would like to...
What want to do There is a variable that remain unchanged once the initial value is determined. However, it cannot be determined yet when...
What want to do As the title suggests. Place two widgets in one line on the screen One in the center of the screen and the other on the...
Comments