Building Layouts in Flutter - Flutter
Building Layouts in Flutter - Flutter
Building Layouts in Flutter - Flutter
This is a guide to building layouts in Flutter. You’ll build the layout for the following screenshot:
This guide then takes a step back to explain Flutter’s approach to layout, and shows how to place a single widget on the screen. After a discussion of
how to lay widgets out horizontally and vertically, some of the most common layout widgets are covered.
Building a layout
Step 0: Set up
Step 1: Diagram the layout
Step 2: Implement the title row
Step 3: Implement the button row
Step 4: Implement the text section
Step 5: Implement the image section
Step 6: Put it together
Flutter’s approach to layout
Lay out a widget
Lay out multiple widgets vertically and horizontally
Aligning widgets
Sizing widgets
https://flutter.io/tutorials/layout/ 1/26
9/13/2018 Building Layouts in Flutter - Flutter
Packing widgets
Nesting rows and columns
Common layout widgets
Standard widgets
Material Components
Resources
Building a layout
If you want a “big picture” understanding of the layout mechanism, start with Flutter’s approach to layout.
Step 0: Set up
First, get the code:
First, identify the larger elements. In this example, four elements are arranged into a column: an image, two rows, and a block of text.
https://flutter.io/tutorials/layout/ 2/26
9/13/2018 Building Layouts in Flutter - Flutter
Next, diagram each row. The rst row, called the Title section, has 3 children: a column of text, a star icon, and a number. Its rst child, the column,
contains 2 lines of text. That rst column takes a lot of space, so it must be wrapped in an Expanded widget.
The second row, called the Button section, also has 3 children: each child is a column that contains an icon and text.
https://flutter.io/tutorials/layout/ 3/26
9/13/2018 Building Layouts in Flutter - Flutter
Once the layout has been diagrammed, it’s easiest to take a bottom-up approach to implementing it. To minimize the visual confusion of deeply
nested layout code, place some of the implementation in variables and functions.
Putting the rst row of text inside a Container enables adding padding. The second child in the Column, also text, displays as grey.
The last two items in the title row are a star icon, painted red, and the text “41”. Place the entire row in a Container and pad along each edge with 32
pixels.
Note: If you have problems, you can check your code against lib/main.dart on GitHub.
Tip: When pasting code into your app, indentation can become skewed. You can x this in your Flutter editor using the automatic reformatting
support.
Tip: For a faster development experience try Flutter’s hot reload feature Hot reload allows you to modify your code and see the changes
https://flutter.io/tutorials/layout/ 4/26
9/13/2018 Building Layouts in Flutter - Flutter
Tip: For a faster development experience, try Flutter s hot reload feature. Hot reload allows you to modify your code and see the changes
without fully restarting the app. The Flutter enabled IDEs support ‘hot reload on save’, or you can trigger from the command line. For more
information about reloads, see Hot Reloads vs. Full Application Restarts.
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
//...
}
Since the code for building each row would be almost identical, it’s most e cient to create a nested function, such as buildButtonColumn() , which
takes an Icon and Text, and returns a column with its widgets painted in the primary color.
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(icon, color: color),
Container(
margin: const EdgeInsets.only(top: 8.0),
child: Text(
label,
style: TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.w400,
color: color,
),
),
),
],
);
}
//...
}
The build function adds the icon directly to the column. Put text into a Container to add padding above the text, separating it from the icon.
Build the row containing these columns by calling the function and passing the icon and text speci c to that column. Align the columns along the
main axis using MainAxisAlignment.spaceEvenly to arrange the free space evenly before, between, and after each column.
buildButtonColumn(Icons.near_me, 'ROUTE'),
b ildB tt C l (I h 'SHARE')
https://flutter.io/tutorials/layout/ 5/26
9/13/2018 Building Layouts in Flutter - Flutter
buildButtonColumn(Icons.share, 'SHARE'),
],
),
);
//...
}
return MaterialApp(
//...
body: ListView(
children: [
Image.asset(
'images/lake.jpg',
height: 240.0,
fit: BoxFit.cover,
),
// ...
],
),
//...
);
BoxFit.cover tells the framework that the image should be as small as possible but cover its entire render box.
//...
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Top Lakes'),
),
body: ListView(
children: [
Image.asset(
'images/lake.jpg',
idth 600 0
https://flutter.io/tutorials/layout/ 6/26
9/13/2018 Building Layouts in Flutter - Flutter
width: 600.0,
height: 240.0,
fit: BoxFit.cover,
),
titleSection,
buttonSection,
textSection,
],
),
),
);
//...
That’s it! When you hot reload the app, you should see the same layout shown in the screenshots. You can add interactivity to this layout by following
Adding Interactivity to Your Flutter App.
The core of Flutter’s layout mechanism is widgets. In Flutter, almost everything is a widget—even layout models are widgets. The images, icons, and
text that you see in a Flutter app are all widgets. But things you don’t see are also widgets, such as the rows, columns, and grids that arrange,
constrain, and align the visible widgets.
You create a layout by composing widgets to build more complex widgets. For example, the screenshot on the left shows 3 icons with a label under
each one:
The second screenshot displays the visual layout, showing a row of 3 columns where each column contains an icon and a label.
Note: Most of the screenshots in this tutorial are displayed with debugPaintSizeEnabled set to true so you can see the visual layout. For more
information, see Visual debugging, a section in Debugging Flutter Apps.
https://flutter.io/tutorials/layout/ 7/26
9/13/2018 Building Layouts in Flutter - Flutter
Most of this should look as you might expect, but you might be wondering about the Containers (shown in pink). Container is a widget that allows you
to customize its child widget. Use a Container when you want to add padding, margins, borders, or background color, to name some of its capabilities.
In this example, each Text widget is placed in a Container to add margins. The entire Row is also placed in a Container to add padding around the row.
The rest of the UI in this example is controlled by properties. Set an Icon’s color using its color property. Use Text’s style property to set the font,
its color, weight, and so on. Columns and Rows have properties that allow you to specify how their children are aligned vertically or horizontally, and
how much space the children should occupy.
How do you layout a single widget in Flutter? This section shows how to create a simple widget and display it on screen. It also shows the entire code
for a simple Hello World app.
In Flutter, it takes only a few steps to put text, an icon, or an image on the screen.
Note: Flutter apps are written in the Dart language. If you know Java or similar object-oriented coding languages, Dart will feel very familiar. If
not, you might try DartPad, an interactive Dart playground you can use from any browser. The Language Tour provides an overview of the
features of the Dart Language.
Center(
child: Text('Hello World', style: TextStyle(fontSize: 32.0))
For a Material app, you can add the Center widget directly to the body property for the home page.
Note: The Material Components library implements widgets that follow Material Design principles. When designing your UI, you can
exclusively use widgets from the standard widgets library, or you can use widgets from Material Components. You can mix widgets from
both libraries, you can customize existing widgets, or you can build your own set of custom widgets.
For a non-Material app, you can add the Center widget to the app’s build() method:
void main() {
runApp(MyApp());
}
Note that, by default, the non-Material app doesn’t include an AppBar, title, or background color. If you want these features in a non-Material app,
https://flutter.io/tutorials/layout/ 9/26
9/13/2018 Building Layouts in Flutter - Flutter
you have to build them yourself. This app changes the background color to white and the text to dark grey to mimic a Material app.
That’s it! When you run the app, you should see:
Row and Column are two of the most commonly used layout patterns.
Row and Column each take a list of child widgets.
A child widget can itself be a Row, Column, or other complex widget.
You can specify how a Row or Column aligns its children, both vertically and horizontally.
You can stretch or constrain speci c child widgets.
You can specify how child widgets use the Row’s or Column’s available space.
Contents
Aligning widgets
Sizing widgets
Packing widgets
Nesting rows and columns
To create a row or column in Flutter, you add a list of children widgets to a Row or Column widget. In turn, each child can itself be a row or column, and
so on. The following example shows how it is possible to nest rows or columns inside of rows or columns.
This layout is organized as a Row. The row contains two children: a column on the left, and an image on the right:
https://flutter.io/tutorials/layout/ 10/26
9/13/2018 Building Layouts in Flutter - Flutter
You’ll implement some of Pavlova’s layout code in Nesting rows and columns.
Note: Row and Column are basic primitive widgets for horizontal and vertical layouts—these low-level widgets allow for maximum customization.
Flutter also offers specialized, higher level widgets that might be su cient for your needs. For example, instead of Row you might prefer ListTile,
an easy-to-use widget with properties for leading and trailing icons, and up to 3 lines of text. Instead of Column, you might prefer ListView, a
column-like layout that automatically scrolls if its content is too long to t the available space. For more information, see Common layout widgets.
Aligning widgets
You control how a row or column aligns its children using the mainAxisAlignment and crossAxisAlignment properties. For a row, the main axis
runs horizontally and the cross axis runs vertically. For a column, the main axis runs vertically and the cross axis runs horizontally.
https://flutter.io/tutorials/layout/ 11/26
9/13/2018 Building Layouts in Flutter - Flutter
The MainAxisAlignment and CrossAxisAlignment classes offer a variety of constants for controlling alignment.
Note: When you add images to your project, you need to update the pubspec le to access them—this example uses Image.asset to display the
images. For more information, see this example’s pubspec.yaml le, or Adding Assets and Images in Flutter. You don’t need to do this if you’re
referencing online images using Image.network.
In the following example, each of the 3 images is 100 pixels wide. The render box (in this case, the entire screen) is more than 300 pixels wide, so
setting the main axis alignment to spaceEvenly divides the free horizontal space evenly between, before, and after each image.
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Image.asset('images/pic1.jpg'),
Columns work the same way as rows. The following example shows a column of 3 images, each is 100 pixels high. The height of the render box (in
this case, the entire screen) is more than 300 pixels, so setting the main axis alignment to spaceEvenly divides the free vertical space evenly
between, above, and below each image.
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Image.asset('images/pic1.jpg'),
https://flutter.io/tutorials/layout/ 12/26
9/13/2018 Building Layouts in Flutter - Flutter
Note: When a layout is too large to t the device, a red strip appears along the affected edge. For example, the row in the following screenshot is
too wide for the device’s screen:
Widgets can be sized to t within a row or column by using an Expanded widget, which is described in the Sizing widgets section below.
Sizing widgets
Perhaps you want a widget to occupy twice as much space as its siblings. You can place the child of a row or column in an Expanded widget to
control widget sizing along the main axis. The Expanded widget has a flex property, an integer that determines the ex factor for a widget. The
default ex factor for an Expanded widget is 1.
For example, to create a row of three widgets where the middle widget is twice as wide as the other two widgets, set the ex factor on the middle
widget to 2:
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
hild I t('i / i 1 j ')
https://flutter.io/tutorials/layout/ 13/26
9/13/2018 Building Layouts in Flutter - Flutter
child: Image.asset('images/pic1.jpg'),
),
Expanded(
flex: 2,
child: Image.asset('images/pic2.jpg'),
),
Expanded(
To x the example in the previous section where the row of 3 images was too wide for its render box, and resulted in the red strip, wrap each widget
with an Expanded widget. By default, each widget has a ex factor of 1, assigning one-third of the row to each widget.
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Image.asset('images/pic1.jpg'),
),
Expanded(
child: Image.asset('images/pic2.jpg'),
),
Expanded(
Packing widgets
By default, a row or column occupies as much space along its main axis as possible, but if you want to pack the children closely together, set its
mainAxisSize to MainAxisSize.min . The following example uses this property to pack the star icons together.
// ...
}
https://flutter.io/tutorials/layout/ 14/26
9/13/2018 Building Layouts in Flutter - Flutter
The outlined section is implemented as two rows. The ratings row contains ve stars and the number of reviews. The icons row contains three
columns of icons and text.
The ratings variable creates a row containing a smaller row of 5 star icons, and text:
Text(
'170 R i '
https://flutter.io/tutorials/layout/ 15/26
9/13/2018 Building Layouts in Flutter - Flutter
'170 Reviews',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w800,
fontFamily: 'Roboto',
letterSpacing: 0.5,
fontSize: 20.0,
),
),
],
),
);
//...
}
}
Tip: To minimize the visual confusion that can result from heavily nested layout code, implement pieces of the UI in variables and functions.
The icons row, below the ratings row, contains 3 columns; each column contains an icon and two lines of text, as you can see in its widget tree:
The leftColumn variable contains the ratings and icons rows, as well as the title and text that describes the Pavlova:
The left column is placed in a Container to constrain its width. Finally, the UI is constructed with the entire row (containing the left column and the
image) inside a Card.
The Pavlova image is from Pixabay and is available under the Creative Commons license. You can embed an image from the net using
Image.network but, for this example, the image is saved to an images directory in the project, added to the pubspec le, and accessed using
Images.asset . For more information, see Adding Assets and Images in Flutter.
body: Center(
child: Container(
margin: EdgeInsets.fromLTRB(0.0, 40.0, 0.0, 30.0),
height: 600.0,
child: Card(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 440.0,
child: leftColumn,
),
mainImage,
],
),
),
),
),
Tip: The Pavlova example runs best horizontally on a wide device, such as a tablet. If you are running this example in the iOS simulator, you can
https://flutter.io/tutorials/layout/ 17/26
9/13/2018 Building Layouts in Flutter - Flutter
select a different device using the Hardware > Device menu. For this example, we recommend the iPad Pro. You can change its orientation to
landscape mode using Hardware > Rotate. You can also change the size of the simulator window (without changing the number of logical pixels)
using Window > Scale.
The following widgets fall into two categories: standard widgets from the widgets library, and specialized widgets from the Material Components
library. Any app can use the widgets library but only Material apps can use the Material Components library.
Standard widgets
Container
GridView
ListView
Stack
Material Components
Card
Organizes related info into a box with rounded corners and a drop shadow.
ListTile
Organizes up to 3 lines of text, and optional leading and trailing icons, into a row.
Container
Many layouts make liberal use of Containers to separate widgets with padding, or to add borders or margins. You can change the device’s background
by placing the entire layout into a Container and changing its background color or image.
Container summary:
Container examples:
In addition to the example below, many examples in this tutorial use Container. You can also nd more Container examples in the Flutter Gallery.
This layout consists of a column of two rows, each containing 2 images. Each image uses a Container to add a rounded grey border and margins. The
Column, which contains the rows of images, uses a Container to change the background color to a lighter grey.
https://flutter.io/tutorials/layout/ 18/26
9/13/2018 Building Layouts in Flutter - Flutter
GridView
Use GridView to lay widgets out as a two-dimensional list. GridView provides two pre-fabricated lists, or you can build your own custom grid. When a
GridView detects that its contents are too long to t the render box, it automatically scrolls.
GridView summary:
Note: When displaying a two dimensional list where it’s important which row and column a cell occupies (for example it’s the entry in the “calorie”
https://flutter.io/tutorials/layout/ 19/26
9/13/2018 Building Layouts in Flutter - Flutter
Note: When displaying a two-dimensional list where it s important which row and column a cell occupies (for example, it s the entry in the calorie
column for the “avocado” row), use Table or DataTable.
GridView examples:
Uses GridView.extent to create a grid with tiles a maximum 150 pixels wide.
Dart code: main.dart, snippet below
Images: images
Pubspec: pubspec.yaml
Uses GridView.count to create a grid that’s 2 tiles wide in portrait mode, and 3 tiles wide in landscape mode. The titles are created by setting the
footer property for each GridTile.
Dart code: grid_list_demo.dart from the Flutter Gallery
return List<Container>.generate(
count,
(int index) =>
Container(child: Image.asset('images/pic${index+1}.jpg')));
https://flutter.io/tutorials/layout/ 20/26
9/13/2018 Building Layouts in Flutter - Flutter
Widget buildGrid() {
return GridView.extent(
maxCrossAxisExtent: 150.0,
padding: const EdgeInsets.all(4.0),
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
children: _buildGridTileList(30));
}
ListView
ListView, a column-like widget, automatically provides scrolling when its content is too long for its render box.
ListView summary:
ListView examples:
Uses ListView to display a list of businesses using ListTiles. A Divider separates the theaters from the restaurants.
Dart code: main.dart, snippet below
Icons: Icons class
Pubspec: pubspec.yaml
https://flutter.io/tutorials/layout/ 21/26
9/13/2018 Building Layouts in Flutter - Flutter
Uses ListView to display the Colors from the Material Design palette for a particular color family.
Dart code: colors_demo.dart from the Flutter Gallery
Stack
Use Stack to arrange widgets on top of a base widget—often an image. The widgets can completely or partially overlap the base widget.
Stack summary:
You can choose to clip children that exceed the render box
Stack examples:
Uses Stack to overlay a Container (that displays its Text on a translucent black background) on top of a Circle Avatar. The Stack offsets the text using
the alignment property and Alignments.
Dart code: main.dart, snippet below
Image: images
Pubspec: pubspec.yaml
Uses Stack to overlay a gradient to the top of the image. The gradient ensures that the toolbar’s icons are distinct against the image.
Dart code: contacts_demo.dart from the Flutter Gallery
Card
A Card, from the Material Components library, contains related nuggets of information and can be composed from almost any widget, but is often
used with ListTile. Card has a single child, but its child can be a column, row, list, grid, or other widget that supports multiple children. By default, a
Card shrinks its size to 0 by 0 pixels. You can use SizedBox to constrain the size of a card.
In Flutter, a Card features slightly rounded corners and a drop shadow, giving it a 3D effect. Changing a Card’s elevation property allows you to
https://flutter.io/tutorials/layout/ 23/26
9/13/2018 Building Layouts in Flutter - Flutter
control the drop shadow effect. Setting the elevation to 24.0, for example, visually lifts the Card further from the surface and causes the shadow to
become more dispersed. For a list of supported elevation values, see Elevation and Shadows in the Material guidelines. Specifying an unsupported
value disables the drop shadow entirely.
Card summary:
Card examples:
A Card containing 3 ListTiles and sized by wrapping it with a SizedBox. A Divider separates the rst and second ListTiles.
leading: Icon(
I t t il
https://flutter.io/tutorials/layout/ 24/26
9/13/2018 Building Layouts in Flutter - Flutter
Icons.contact_mail,
color: Colors.blue[500],
),
),
],
),
),
);
//...
}
ListTile
Use ListTile, a specialized row widget from the Material Components library, for an easy way to create a row containing up to 3 lines of text and
optional leading and trailing icons. ListTile is most commonly used in Card or ListView, but can be used elsewhere.
ListTile summary:
ListTile examples:
Resources
The following resources may help when writing layout code.
Widget Overview
Describes many of the widgets available in Flutter.
HTML/CSS Analogs in Flutter
For those familiar with web programming, this page maps HTML/CSS functionality to Flutter features.
Flutter Gallery
Demo app showcasing many Material Design widgets and other Flutter features.
Flutter API documentation
Reference documentation for all of the Flutter libraries.
Dealing with Box Constraints in Flutter
Discusses how widgets are constrained by their render boxes.
Adding Assets and Images in Flutter
Explains how to add images and other assets to your app’s package.
https://flutter.io/tutorials/layout/ 26/26