Nesting rows and columns in Flutter

Nesting is a powerful concept allowing us to create complex and flexible layouts. When we nest rows and columns, we put one row or column inside another. This lets us make our display organized, like putting a row inside a column or a column inside a row, and arrange widgets in both horizontal and vertical directions. This is what we'll be implementing in our Answer today.

Flutter

Flutter is a UI development toolkit primarily used for building applications for various platforms using a single codebase. It is completely open-source and is a product of Google.

Simply put, this means that developers can write the code once and use it on different platforms without having to start from scratch for each one.

Flutter in a few words
Flutter in a few words

Note: We offer various courses if you aim to continue your journey in learning Flutter!

Beginning Flutter: Android Mobile App Development

Learn Dart: First Step to Flutter

Dart

Flutter needs a programming language to build and run applications. Dart is used as the primary language for developing applications with the Flutter framework. We will be using Dart in our code as well.

How Flutter works
How Flutter works

Note: Before proceeding with the answer, ensure that your Flutter setup is complete.

Nesting in Flutter

In Flutter, nesting means putting one widget inside another, just like placing a box inside another box. This basically allows us to create more complex layouts by combining different widgets together, in turn making the code and display more organized.

Example of nesting
Example of nesting

Rows and columns

First, let's understand rows and columns in Flutter.

  1. Imagine a row as a horizontal line on your screen. We can place widgets side by side in a row, which will be arranged from left to right in a straight line.

  2. Similarly, imagine a column as a vertical line on your screen. We can place widgets on top of each other in a column, which will be arranged from top to bottom in a straight line.

Nesting columns in a row

The layout component, Row, allows us to add as many children components as we want, including Column components. We can use the children: [..] syntax to achieve this type of nesting.

Code

import 'package:flutter/material.dart';
void main() {
runApp(RowWithTwoColumns());
}
class RowWithTwoColumns extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.star),
Text('Column 1'),
],
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.star),
Text('Column 2'),
],
),
],
),
),
),
);
}
}
Basic nesting code (columns within rows)

Output

Two columns in a single row
Two columns in a single row

Nesting rows in a column

The layout component, Column, allows us to add as many children components as we want, including Row components. We can use the children: [..] syntax to achieve this type of nesting.

Code

import 'package:flutter/material.dart';
void main() {
runApp(ColumnWithTwoRows());
}
class ColumnWithTwoRows extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.star),
Text('Row 1'),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.star),
Text('Row 2'),
],
),
],
),
),
),
);
}
}
Basic nesting code (rows within columns)

Output

Two rows in a single column
Two rows in a single column

Car platform scenario

Let's take a scenario where we have to create an application to learn more about cars and check out their ratings. For such an application's user interface, we could think of adding components like headings, a short description, rating stars, and an image.

A bird's eye view of the user interface could resemble the following image.

First go at the UI of such an application
First go at the UI of such an application

Complete code

import 'package:flutter/material.dart';

void main() {
  runApp(CarRatingApp());
}

class CarRatingApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text(
            'Car Rating Platform',
            style: TextStyle(fontSize: 24),
          ),
          centerTitle: true,
          backgroundColor: Colors.deepPurple,
          elevation: 0,
        ),
        body: Center(
          child: Container(
            width: 800, 
            margin: const EdgeInsets.all(20),
            height: 600,
            child: Card(
              color: Colors.black87,
              child: Row(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Expanded(
                    child: LeftColumn(),
                  ),
                  SizedBox(
                    width: 400, 
                    height: 400,
                    child: Image.asset('assets/bugatti.png'),
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}

class LeftColumn extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(20),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            'Bugatti Veyron',
            style: TextStyle(
              fontSize: 28,
              fontWeight: FontWeight.bold,
              color: Colors.white,
            ),
          ),
          SizedBox(height: 10),
          Text(
            'A masterpiece of engineering and design!',
            style: TextStyle(
              fontSize: 18,
              color: Colors.white,
            ),
          ),
          SizedBox(height: 20),
          RatingsRow(),
          SizedBox(height: 20),
          IconsRow(),
          SizedBox(height: 20),
          Expanded(
            child: Text(
              'Bugatti Veyron is a mid-engine sports car designed and developed in Germany by the Volkswagen Group and manufactured in Molsheim, Alsace, France. It is named after the racing driver Pierre Veyron. The original version has a top speed of 407 km/h (253 mph).',
              style: TextStyle(
                fontSize: 16,
                color: Colors.white,
              ),
              textAlign: TextAlign.justify, 
            ),
          ),
        ],
      ),
    );
  }
}

class RatingsRow extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: [
        Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            Icon(Icons.star, color: Colors.amber[500]),
            Icon(Icons.star, color: Colors.amber[500]),
            Icon(Icons.star, color: Colors.amber[500]),
            Icon(Icons.star, color: Colors.amber[500]),
          ],
        ),
        Text(
          '170 Reviews',
          style: TextStyle(
            color: Colors.white,
            fontWeight: FontWeight.w800,
            fontFamily: 'Roboto',
            letterSpacing: 0.5,
            fontSize: 20,
          ),
        ),
      ],
    );
  }
}

class IconsRow extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    const descTextStyle = TextStyle(
      color: Colors.white,
      fontWeight: FontWeight.w800,
      fontFamily: 'Roboto',
      letterSpacing: 0.5,
      fontSize: 18,
      height: 2,
    );

    return DefaultTextStyle.merge(
      style: descTextStyle,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          Column(
            children: [
              Icon(Icons.kitchen, color: Colors.amber[500]),
              Text('Top Speed:'),
              Text('267 mph'),
            ],
          ),
          Column(
            children: [
              Icon(Icons.timer, color: Colors.amber[500]),
              Text('0-60 mph:'),
              Text('2.5 sec'),
            ],
          ),
          Column(
            children: [
              Icon(Icons.restaurant, color: Colors.amber[500]),
              Text('Engine:'),
              Text('8.0L W16'),
            ],
          ),
        ],
      ),
    );
  }
}

Nesting explanation

After we've created our major top-level widgets CarRatingApp, MaterialApp, Scaffold, and AppBar, we will create our components using different kinds of nesting. Let's dive deeper into the nesting structure.

Center: Centers its child widget in the scaffold.

  • Container: Defines the main content area with margins and a fixed height.

    • Card: Provides a charcoal gray colored stylized container with rounded corners and elevation.

      • Row: Organizes the left and right content side by side.

        • Expanded: A flexible widget that takes up the available remaining space horizontally and contains LeftColumn.

          • Container: Provides padding and background color for the left column.

            • Column: Organizes the left-side content in a vertical line.

              • Text: Displays the title "Bugatti Veyron" in bold and white color.

              • SizedBox: Adds some vertical spacing. This is only to make the visuals better.

              • Text: Displays the description "A masterpiece of engineering and design!".

              • SizedBox: Adds some more vertical spacing.

              • RatingsRow: Contains star icons and the number of reviews.

                • Row: Organizes star icons and the number of reviews side by side.

                  • Row: Contains individual star icons to show reviews.

                  • Text: Displays "170 Reviews" in white color and in bold.

              • SizedBox: Adds vertical spacing.

              • IconsRow: Contains a few icons and information.

                • Row: Organizes icons and their corresponding information side by side.

                  • Column: Organizes the single icon and information in a vertical line.

                    • Icon: Displays a kitchen icon.

                    • Text: Displays "Top Speed:".

                    • Text: Displays "267 mph".

                  • Column: Organizes the single icon and information in a vertical line.

                    • Icon: Displays a timer icon.

                    • Text: Displays "0-60 mph:".

                    • Text: Displays "2.5 sec".

                  • Column: Organizes the single icon and information in a vertical line.

                    • Icon: Displays a restaurant icon.

                    • Text: Displays "Engine:".

                    • Text: Displays "8.0L W16".

        • SizedBox: Adds horizontal spacing between our left and right content.

        • SizedBox: Defines our image's size.

        • Image: Displays the Bugatti Veyron image loaded from the assets.

        • SizedBox: Adds vertical spacing between the image and the paragraph.

        • Expanded: Allows the paragraph to take up all the available space.

          • Text: Displays the paragraph text about Bugatti Veyron and justifies it.

Woah, that sure seemed a lot, but you'll be easily able to map the components with the output and use such nestings in your own code in no time!

Final output

This is what our application looks like when it first runs.

The complete application
The complete application

This is a closeup of our Bugatti Veyron card. Try to identify as many nestings as you can!

Close up of the card
Close up of the card

End note

Simply put, nesting rows and columns in Flutter allows us to create flexible and organized layouts by combining multiple widgets together, either side by side in a row or on top of each other in a column. This makes it so much easier to design and build user interfaces for our applications.

Explore other Flutter Answers

Note: Explore the Flutter series here!

Test your knowledge on nesting rows and columns!

Question

If we want to place some text side by side with an image, what should the structure be?

Show Answer

Free Resources

Copyright ©2024 Educative, Inc. All rights reserved