Flutter - Using Row Widget Examples

This tutorial shows you how to use Row widget in Flutter.

Row is a widget that displays its children in a horizontal array. It's a widget to use if you have multiple widgets to be displayed in the same horizontal row. In this tutorial, I'm going to show you how to use the widget and how to customize the layout.

Using Row Widget

Below is the constructor to use.

  Row({
    Key key,
    MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
    MainAxisSize mainAxisSize = MainAxisSize.max,
    CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
    TextDirection textDirection,
    VerticalDirection verticalDirection = VerticalDirection.down,
    TextBaseline textBaseline = TextBaseline.alphabetic,
    List<Widget> children = const <Widget>[],
  }

There is no required argument. The most common argument to pass is children which contains the list of widgets to be arranged in a horizontal row.

  Container(
    height: 100,
    color: Color.fromARGB(100, 200, 200, 200),
    child: Row(
      children: [
        FlutterLogo(
          size: 50,
        ),
        const Text('Welcome to woolha.com', style: const TextStyle(color: Colors.teal)),
        Icon(Icons.widgets),
      ],
    ),
  )

Output:

Flutter - Row

Set Main Axis Alignment

You can set how the children should be aligned in the main axis by passing mainAxisAlignment argument. By default, the children will be aligned to the start of the main axis. The possible values are:

  • start: Place the children as close to the start of the main axis as possible.
  • end: Place the children as close to the end of the main axis as possible.
  • center: Place the children as close to the middle of the main axis as possible.
  • spaceAround: Place the free space evenly between the children as well as half of that space before and after the first and last child.
  • spaceBetween: Place the free space evenly between the children.
  • spaceEvenly: Place the free space evenly between the children as well as before and after the first and last child.

Below is an example with the mainAxisAlignment is set to center.

  Container(
    height: 100,
    color: Color.fromARGB(100, 200, 200, 200),
    child: Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        FlutterLogo(
          size: 50,
        ),
        const Text('Welcome to woolha.com', style: const TextStyle(color: Colors.teal)),
        Icon(Icons.widgets),
      ],
    ),
  )

Output:

Flutter - Row - mainAxisAlignment - center

Below is the comparison of all possible values.

start
Flutter - Row - mainAxisAlignment - start

center
Flutter - Row - mainAxisAlignment - center

end
Flutter - Row - mainAxisAlignment - end

spaceAround
Flutter - Row - mainAxisAlignment - spaceAround

spaceBetween
Flutter - Row - mainAxisAlignment - spaceBetween

spaceEvenly
Flutter - Row - mainAxisAlignment - spaceEvenly

Set Cross Axis Alignment

The alignment of the children in the cross axis can be set by passing crossAxisAlignment argument. If you don't pass the argument, the default cross axis alignment is center. The possible values are:

  • start: Place the children as close to the start of the cross axis as possible.
  • end: Place the children as close to the end of the cross axis as possible.
  • center: Place the children so that their centers align with the middle of the cross axis.
  • stretch: Require the children to fill the cross axis.
  • baseline: Place the children along the cross axis such that their baselines match.

Here's an example with the crossAxisAlignment is set to baseline.

  Container(
    height: 100,
    color: Color.fromARGB(100, 200, 200, 200),
    child: Row(
      crossAxisAlignment: CrossAxisAlignment.baseline,
      children: [
        FlutterLogo(
          size: 50,
        ),
        const Text('Welcome to woolha.com', style: const TextStyle(color: Colors.teal)),
        Icon(Icons.widgets),
      ],
    ),
  )

Output:

Flutter - Row - crossAxisAlignment - baseline

The difference of those possible values can be seen below.

start
Flutter - Row - crossAxisAlignment - start

center
Flutter - Row - crossAxisAlignment - center

end
Flutter - Row - crossAxisAlignment - end

baseline
Flutter - Row - crossAxisAlignment - baseline

stretch
Flutter - Row - crossAxisAlignment - stretch

Set Main Axis Size

By default, the main axis size maximizes the amount of free space along the main axis. That means the width of the widget will be as width as possible. To make it as narrow as possible, you can set the mainAxisSize argument to min.

  • min: Minimize the amount of free space along the main axis
  • max: Maximize the amount of free space along the main axis

Keep in mind that incoming constraints may affect the main axis size. The example below sets the mainAxisSize to min. As a result, the width of the Row is the total width of its children.

  Container(
    height: 100,
    color: Color.fromARGB(100, 200, 200, 200),
    child: Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        FlutterLogo(
          size: 50,
        ),
        const Text('Welcome to woolha.com', style: const TextStyle(color: Colors.teal)),
        Icon(Icons.widgets),
      ],
    ),
  )

Output:

Flutter - Row - mainaxissize - min

Set Text Direction

From the previous examples, you can see that the children are rendered from left to right according to the order they're defined. You can change it by passing textDirection argument. In the example below, the textDirection is set to rtl (right-to-left). Therefore, the first child is rendered on the rightmost position, the second child is on the left of the first child, and so on.

  Container(
    height: 100,
    color: Color.fromARGB(100, 200, 200, 200),
    child: Row(
      textDirection: TextDirection.rtl,
      children: [
        FlutterLogo(
          size: 50,
        ),
        const Text('Welcome to woolha.com', style: const TextStyle(color: Colors.teal)),
        Icon(Icons.widgets),
      ],
    ),
  )

Output:

Flutter - Row - textDirection - rtl

Layout Algorithm

To understand how Flutter places the children of a Row widget, you need to understand the layout algorithm.

  • Layout each child a null or zero flex factor with unbounded horizontal constraints and the incoming vertical constraints. If the crossAxisAlignment is CrossAxisAlignment.stretch, use tight vertical constraints that match the incoming max height.
  • Take children with non-zero flex factors and set the width according to the flex factor.
  • Take the remaining children and set the vertical constraints to be the same as in step 1. The horizontal constraints are based on the space allocated in step 2. Children with Flexible.fit property is set to FlexFit.tight will be given tight constraints. Otherwise, children with Flexible.fit property is set to FlexFit.loose will be given loose constraints.
  • Set the height of the Row to be the maximum height of the children. That means the height will always satisfy the vertical constraints).
  • Set the width of the Row depending on mainAxisSize property.
  • Move the position of each child according to mainAxisAlignment and crossAxisAlignment.

For controlling the width of the children, you may need to wrap some of the children as the child of another widget such as Expanded or Flexible. Below is an example that wraps the second child of the above examples as the child of an Expanded widget. Therefore, the width of the second child will fill the available space.

  Container(
    height: 100,
    color: Color.fromARGB(100, 200, 200, 200),
    child: Row(
      children: [
        FlutterLogo(
          size: 50,
        ),
        Expanded(
          child: const Text('Woolha.com is a blog about programming', style: const TextStyle(color: Colors.teal)),
        ),
        Icon(Icons.widgets),
      ],
    ),
  )

Output:

Flutter - Row - Expanded

Row Parameters

  • Key key: The widget's key.
  • MainAxisAlignment mainAxisAlignment: How the children should be placed along the main axis. Defaults to MainAxisAlignment.start.
  • MainAxisSize mainAxisSize: How much space should be occupied in the main axis.. Defaults to MainAxisSize.max.
  • CrossAxisAlignment crossAxisAlignment: How the children should be placed along the cross axis. Defaults to CrossAxisAlignment.center.
  • TextDirection textDirection: used to set the order to lay children out horizontally and how start and end should be interpreted in the horizontal direction..
  • VerticalDirection verticalDirection: used to set the order to lay children out vertically and how start and end should be interpreted in the vertical direction. Defaults to VerticalDirection.down.
  • TextBaselinetextBaseline : The baseline to use if aligning items using their baseline. Defaults to TextBaseline.alphabetic.
  • List<Widget> children: The widgets below this widget in the tree. Defaults to const []

Full Code

  import 'package:flutter/material.dart';
  
  void main() => runApp(MyApp());
  
  class MyApp extends StatelessWidget {
  
    @override
    Widget build(BuildContext context) {
      return MaterialApp(
        title: 'Woolha.com Flutter Tutorial',
        home: _RowExample(),
      );
    }
  }
  
  class _RowExample extends StatelessWidget {
  
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          title: const Text('Woolha.com Flutter Tutorial'),
        ),
        body: Container(
          height: 100,
          color: Color.fromARGB(100, 200, 200, 200),
          child: Row(
  //          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  //          textDirection: TextDirection.rtl,
  //          crossAxisAlignment: CrossAxisAlignment.baseline,
            children: [
              FlutterLogo(
                size: 50,
              ),
  //            const Text('Welcome to woolha.com', style: const TextStyle(color: Colors.teal)),
            Expanded(
              child: const Text('Woolha.com is a blog about programming', style: const TextStyle(color: Colors.teal)),
            ),
              Icon(Icons.widgets),
            ],
          ),
        ),
      );
    }
  }

Summary

That's how to use Flutter's Row widget. This is the widget to use if you have some widgets to be displayed in the same row. The optional named parameters that can be passed to the constructor make it easier to customize how the children should be aligned, the main axis size of the widget, and the direction to render the children.

You can also read about:

  • Column: a widget that displays its children in a vertical array.
  • Wrap: a widget that displays its children in multiple horizontal or vertical runs.