Device-Agnostic Design

Flutter Space, Boxes, and Cards


Learning Objectives

  • You know how to define areas around widgets and know how to reserve space for widgets.
  • You know how to group content together and work with cards.

Component space

The space available for a widget and hence the size of the widget is in part determined based on both the widget and the widgets above the widget in the widget hierarchy. As an example, both Row and Column seek to minimize the area available for their children, unless explicitly defined (e.g. by a child widget).

The following example outlines this behavior. The application has two Text widgets and a Container with blue color. When you try out the application, you notice that the blue color is not visible.

Run the program to see the output

This is similar to what we observed previously when working with Container. We can influence the behavior by setting values to the width and height properties of the container; in such a case, the container is not minimized.

The example below would show a small blue area between the texts.

Run the program to see the output

Let’s look at the area available for widgets in another program. In the following example, we seek to show a blue container, a text, and a blue container.

Run the program to see the output

When we launch the above example, depending on the width of the screen, the application shows an area with the message right overflowed and prints information about an exception to the console.

Layout widgets

Flutter provides a handful of Layout widgets that can be used to define how widgets are shown. Four useful widgets include the Expanded widget that can be used to expand a child of a Container, Column, or Row, the SizedBox widget that can be used to reserve a specified area for a widget, the AspectRatio widget that can be used to define the aspect ratio of a widget, and the Padding widget that can be used to define padding around a widget.

Expanded

The Expanded widget has a child property that is given a widget that should take the remaining available space. It can be used for both fitting a widget into the available space as well as to fill a remaining space.

The following example demonstrates using Expanded to fit a widget into the available space. This fixes an overflow exception that we observed in the previous example — now, instead of the text being rendered offscreen, the text is wrapped in the available space.

Run the program to see the output

Similarly, we previously saw an example where a Column that contained a Container led to the Container being not visible at all. Using Expanded, the Container fills the available space, as running the next example demonstrates.

Run the program to see the output

If the program has multiple Expanded widgets in the same Column widget, the available space is divided equally between the widgets. The example below would create two equal sized containers, where one of them would be blue and one of them yellow.

Run the program to see the output

Loading Exercise...

SizedBox

The SizedBox widget is used to restrict the available space for the widget within the SizedBox widget. The space is defined using the width and height properties, while the child widget is defined using the child property.

The following example demonstrates a program that has a 50 pixels wide red area and a blue area that takes up all the remaining space.

Run the program to see the output

The following example builds on top of the above program by dividing the area on the right into two parts. On the upper right corner is an area that is 25 pixels high, while the remaining area is given to the color blue. As you notice, the available blue space is defined based on the screen size.

Run the program to see the output

The above program is already relatively complex due to the quantity of widgets. It uses both rows and columns, as well as containers, and the size of the containers is influenced using the SizedBox and Expanded widgets.

Loading Exercise...

AspectRatio

The AspectRatio widget allows defining the size of a child widget in terms of an aspect ratio — width / height — instead of absolute values. When creating a new AspectRatio widget, the aspect ratio is as a value to the aspectRatio argument, while the child widget is given using the argument child.

As an example, the following application would show a green area that maintains the aspect ratio 2 / 1, i.e. the width of the green area is always twice the height of the green area.

Run the program to see the output

Loading Exercise...

Padding

The Padding widget offers an explicit way for defining padding — an area outside the widget — for a widget. This leaves room “to breathe” and can create a more aesthetic feeling into the user interface.

The following example demonstrates the use of the Padding widget. In the example, a Text widget within an Expanded widget has been wrapped with a Padding if 12 pixels on all sides.

Run the program to see the output

With padding, be it in use in containers or separately, one could, for example, start building commonly used widgets such as cards (which Flutter also directly provides).

The following example shows a self-made card with title and body and three icons (icon options available at Icons documentation); the example also uses the BoxDecoration class for decorating the container — here, we simply set the background and round the borders using BorderRadius.

Run the program to see the output

As mentioned briefly, Flutter provides also ready-made Card widgets that effectively provide styles for content. We’ll take a peek at these next.

Grouping contents

The above SampleCard widget is effectively a widget that is used to group things together. There are also ready-made widgets such as ListTile for grouping content such as title and subtitle, perhaps with some leading or trailing content.

The following example shows an example use for ListTile, where it is being used to display contacts in a column.

Run the program to see the output

ListTile widgets are commonly used with Card widgets, which provides easy styling. Card is a single widget container, which is given a widget to style with the child property.

The following example shows the previous two contacts styled using Card widget.

Run the program to see the output

The ListTile has a handful of properties that can be used to add content to the widget. The property leading sets a widget to the left hand side of the ListTile, while the property trailing sets a widget to the right hand side of the ListTile.

If we would wish to place an icon on the right hand side, we would use the trailing property. These properties can be, for example, used to highlight messaging, as shown in the following example — the example uses a CircleAvatar widget to represent chat participants.

Run the program to see the output
Loading Exercise...