Building layout in Flutter

The article will guide Flutter newbies to understand:

  • Layout layout in Flutter.
  • How to layout vertically and horizontally.
  • How to build a layout in Flutter.

We will build the layout according to this app:

In this article, I will explain the Flutter approach, about the layout and show how to place a widget on the screen. Then will introduce some commonly used layout widgets.

Step 0: Tạo app base

If you haven’t set up your environment yet , follow this tutorial:

  1. Create a basic “Hello World” Flutter app.
  2. Change app bar title and app title to:

Step 1: Layout layout

The first step is to break the layout into the basic components:

  • Identify rows and columns.
  • Does the layout include grid?
  • Are there any components lying on top of each other?
  • Are there tabs?
  • Note areas with alugnment, padding, or borders.

First, identify the big components first. In the example below, 4 elements are arranged in a column: 1 image, 2 rows, and 1 block of text.

Next, diagram each row. The first row - Title - has 3 children: 1 text column, a star icon, and a number. Its first child component is a column of two lines of text. The first column takes up a lot of space so it will have to be wrapped in the Expanded widget.

The second row - Button - also has 3 children: Each child component is a column consisting of icons and text.

Once the layout has been determined, the easiest way to implement it is to write the UI from the bottom up. To make it easier to see and avoid getting confused by nesting lots of code, put some code in different variables and functions.

Step 2: Implement title row

First, you’ll build the column to the left of the title area. Add the following code at the top of the build () function in the MyApp class :

Widget titleSection = Container(
  padding: const EdgeInsets.all(32),
  child: Row(
    children: [
      Expanded(
        /*1*/
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            /*2*/
            Container(
              padding: const EdgeInsets.only(bottom: 8),
              child: Text(
                'Oeschinen Lake Campground',
                style: TextStyle(
                  fontWeight: FontWeight.bold,
                ),
              ),
            ),
            Text(
              'Kandersteg, Switzerland',
              style: TextStyle(
                color: Colors.grey[500],
              ),
            ),
          ],
        ),
      ),
      /*3*/
      Icon(
        Icons.star,
        color: Colors.red[500],
      ),
      Text('41'),
    ],
  ),
);

1 Place Column inside the Expanded widget so that the column spans all the rows of the row. Set attributes crossAxisAlignment is CrossAxisAlignment.start to set the column to the row starting position.

2 Put the first row of text inside a Container so you can padding. The second child in the column is also text, displaying gray.

3 2 last items are the star icon in the title row, the red and the text “41”. Both rows are in a Container and 32 pixels from each side.

Step 3: Implement button row

The button row area consists of 3 columns that use the same layout - an icon above a row of text. The columns in this row are spaced evenly, the text and icons are primary colors.

The code for each column is identical, so we create a private method helper named buildButtonColumn , get color, Icon and Text, return a column with widgets of the color received.

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // ···
  }

  Column _buildButtonColumn(Color color, IconData icon, String label) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Icon(icon, color: color),
        Container(
          margin: const EdgeInsets.only(top: 8),
          child: Text(
            label,
            style: TextStyle(
              fontSize: 12,
              fontWeight: FontWeight.w400,
              color: color,
            ),
          ),
        ),
      ],
    );
  }
}

This function adds the icons directly to the column. Text is in Container with margin top-only, splitting text with icon.

Place a row containing the columns by calling the function and passing in the color, Icon and text that identifies that column. Align columns by the main axis using MainAxisAlignment.spaceEvenly to arrange the spaces evenly before, during and after each column. Add the code below titleSection in the build () function :

Color color = Theme.of(context).primaryColor;

Widget buttonSection = Container(
  child: Row(
    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
    children: [
      _buildButtonColumn(color, Icons.call, 'CALL'),
      _buildButtonColumn(color, Icons.near_me, 'ROUTE'),
      _buildButtonColumn(color, Icons.share, 'SHARE'),
    ],
  ),
);

Add button section to body:

Step 4: Implement text section

Specify the text section as a variable. Place the text in the Container and add padding on each side. Add the code below buttonSection :

Widget textSection = Container(
  padding: const EdgeInsets.all(32),
  child: Text(
    'Lake Oeschinen lies at the foot of the Blüemlisalp in the Bernese '
        'Alps. Situated 1,578 meters above sea level, it is one of the '
        'larger Alpine Lakes. A gondola ride from Kandersteg, followed by a '
        'half-hour walk through pastures and pine forest, leads you to the '
        'lake, which warms to 20 degrees Celsius in the summer. Activities '
        'enjoyed here include rowing, and riding the summer toboggan run.',
    softWrap: true,
  ),
);

Setting softwrap = true , the text line will fill the column width before wrap at word boundaries. Add section text to the body:

Step 5: Implement image section

3 out of 4 components have been completed, leaving only the image. Add an image file to the following example:

  • Create images folder in the top folder of the project.
  • Add lake.jpg .
  • Update pubspec.yaml file to include assets tag. This will make the image available in the code.

Now you can reference the image in the code:

BoxFit.cover shows that the image will be as small as possible but will fill the void surrounding it.

Step 6: Complete

This is the final step, placing all the components in a ListView rather than Column because ListView supports scrolling when the app runs on small screen devices.

Here is finished.

#flutter #dart

Building layout in Flutter
9.00 GEEK