The Expanded
widget is used within a Row
, Column
, or Flex
to distribute available space among its children, either equally or proportionally using the flex
property.
Key takeaways:
The Expanded
widget in Flutter helps a child widget take up extra space within a layout. It stretches the child to fill available space in the direction you’re arranging the widgets (either horizontally or vertically).
Wrapping a child widget with Expanded
allows it to occupy all available space or a specified proportion using the flex
property.
Without flex
, all children in an Expanded
widget share space equally. Adding flex
values assigns space proportionally.
The Expanded
widget is versatile and can be used in both web and mobile applications.
The expandedWithFlex()
and expandedDefault()
methods showcase how Expanded
widgets allocate space differently with and without flex values.
Responsive layouts are a cornerstone of modern app development, and Flutter makes this easier with the Expanded
widget. This widget is designed to dynamically allocate space among child widgets within a Row
or Column
, making your app adaptable to different screen sizes. To customize how much space each widget occupies, you can use the flex
property. This helps resolve any competition for space by assigning different proportions to the children. In this Answer, we’ll explore how the Expanded
widget works through two examples: its default behavior and the use of the flex
property to customize space distribution.
If you're eager to master Flutter layouts, dive into our Answer: Layouts in Flutter and unlock the secrets to building dynamic and responsive UIs.
Expanded
The Expanded
widget is a layout widget that can only have one child assigned to it. In the following example, the Row
widget contains three children created using the childWidget()
function, each wrapped in an Expanded
widget. By default, all children expand equally to fill the available horizontal space, as the main axis is horizontal.
Row(children: [Expanded(child: Container(color: Colors.red,child: const Center(child: Text("Child 1")),),),Expanded(child: Container(color: Colors.green,child: const Center(child: Text("Child 2")),),),Expanded(child: Container(color: Colors.blue,child: const Center(child: Text("Child 3")),),),],)
This code creates a Row
with three Expanded
children, each sharing equal space within the row. Each child widget is wrapped in a container with a unique background color and a centered text label. The layout automatically distributes the available horizontal space evenly among the children.
flex
propertyIn this example, each Expanded
widget is provided with a flex
value. This helps resolve any competition for space by specifying how much space each child should take relative to the others.
Row(children: [Expanded(flex: 4,child: Container(color: Colors.red,child: const Center(child: Text("Flex 4")),),),Expanded(flex: 3,child: Container(color: Colors.green,child: const Center(child: Text("Flex 3")),),),Expanded(flex: 1,child: Container(color: Colors.blue,child: const Center(child: Text("Flex 1")),),),],)
This code defines a Row
with three Expanded
children, each taking up space proportional to their flex
values: 4
, 3
, and 1
. The containers, with distinct colors and text labels, adjust their widths dynamically based on the assigned proportions, creating a responsive layout.
Note: We can use this code for both web and android applications. But in this section, we are only using the flutter web application for the visual demonstration.
Click the ”Run” button to execute the application.
import 'package:flutter/material.dart'; void main() => runApp(ExpandedDemo()); class ExpandedDemo extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: MyExpanded(), ); } } class MyExpanded extends StatefulWidget { @override _MyExpandedState createState() => _MyExpandedState(); } int noFlex = 0; int withFlex = 1; Map<int, String> dropdown = { noFlex: "No `flex` Property", withFlex: 'Using `flex`', }; class _MyExpandedState extends State<MyExpanded> { int _currentOption = 0; String dropDownValue = dropdown[0]; bool isFlex = false; @override void initState() { super.initState(); updateContainer(0); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Expanded Widget"), actions: [ Padding( padding: const EdgeInsets.only(left: 16.0), child: DropdownButton( hint: dropDownValue == null ? Text('Select') : Text(dropDownValue), items: dropdown.keys .map((e) => DropdownMenuItem( child: Text(dropdown[e]), onTap: () { setState(() { _currentOption = e; updateContainer( _currentOption == 0 ? noFlex : withFlex); }); }, value: e, )) .toList(), onChanged: (newValue) { dropDownValue = dropdown[newValue]; }, ), ), ], ), body: isFlex ? expandedWithFlex() : expandedDefault(), ); } Widget expandedWithFlex() { return Row( children: [ Expanded( flex: 4, child: Container( color: Colors.red, child: const Center(child: Text("Flex 4")), ), ), Expanded( flex: 3, child: Container( color: Colors.green, child: const Center(child: Text("Flex 3")), ), ), Expanded( flex: 1, child: Container( color: Colors.blue, child: const Center(child: Text("Flex 1")), ), ), ], ); } Widget expandedDefault() { return Row( children: [ Expanded( child: Container( color: Colors.red, child: const Center(child: Text("Child 1")), ), ), Expanded( child: Container( color: Colors.green, child: const Center(child: Text("Child 2")), ), ), Expanded( child: Container( color: Colors.blue, child: const Center(child: Text("Child 3")), ), ), ], ); } void updateContainer(int option) { setState(() { isFlex = option == withFlex; }); } }
Once the server is up and running, please open the app using the URL provided at “Your app can be found at.”
Let’s understand how the code above works by breaking it down:
Line 1: We import the package:flutter/material.dart
package to use the pre-built design widgets for Flutter.
Lines 5–13: We define a stateless widget class named ExpandedDemo
that returns a MaterialApp
widget in its build() method for building material design apps, such as a theme, navigation, and accessibility support.
Lines 15–18: We define a stateful widget class named MyExpanded
that can change its state during its lifetime.
Lines 75–101: We defined an expandedWithFlex()
method that returns a Row
widget with three child
widgets wrapped under an Expanded
widget. Each widget has a property set, which determines how much space it should occupy along the main axis of its parent widget.
Lines 103–126: We defined an expandedDefault()
method that returns a Row
widget with three child widgets, which are wrapped under an Expanded
widget. Each widget is given a child
widget by calling the function with an empty string as the argument. The widget allows the child widget to expand and fill the available space along the main axis of the Row
.
Expanded
widgetDynamic space allocation: Use the Expanded
widget when you want child widgets within a Row
, Column
, or Flex
to automatically expand and fill the available space along the main axis.
Equal space distribution: It’s ideal when all child widgets share the space equally, making it great for simple, balanced layouts.
Quick layout adjustments: If you don’t need to customize the space allocation of each child, Expanded
provides a quick solution for flexible layouts without too much complexity.
However, if you need more control over how much space each child occupies:
For more control: While Expanded
forces a child widget to take up all available space, the Flexible
widget allows child widgets to take only as much space as they need while still being able to expand if space is available. Consider the Flexible
widget, which allows you to assign specific proportions of space to child widgets, offering more flexibility compared to Expanded
.
Granular adjustments: Use Flexible
when you need child widgets to share space in a non-equal way, based on their assigned flex
values.
Expanded
widgetCombine with other widgets: Use Expanded
with Flexible
or Spacer
widgets for more control over spacing and layout.
Keep it simple: Avoid overcomplicating designs with nested Expanded
widgets.
Test on different screens: Always test your layout on various devices to ensure responsiveness.
Expanded
widgetAutomatic space distribution: Adjusts child sizes dynamically based on available space.
Cleaner layouts: Simplifies the process of creating flexible, adaptable designs.
Code efficiency: Reduces the need for manual size calculations.
The Expanded
widget in Flutter is a powerful tool for creating responsive layouts by distributing available space among child widgets within a Row
or Column
. By using the flex
property, developers can control how much space each child occupies, enabling precise and flexible design adjustments. This functionality makes the Expanded
widget essential for building adaptable user interfaces in both web and mobile Flutter applications. Through examples and practical implementation, this Answer highlights how to effectively utilize Expanded
widgets to achieve dynamic and proportional layouts.
Unlock your full potential with our comprehensive course: Beginning Flutter: Android Mobile App Development. Dive deeper into the topic and gain hands-on experience through expert-led lessons.
Haven’t found what you were looking for? Contact Us