A widget that displays its children in a horizontal array.

To cause a child to expand to fill the available horizontal space, wrap the child in an Expanded widget.

The Row widget does not scroll (and in general it is considered an error to have more children in a Row than will fit in the available room). If you have a line of widgets and want them to be able to scroll if there is insufficient room, consider using a ListView.

For a vertical variant, see Column.

If you only have one child, then consider using Align or Center to position the child.

Sample code

This example divides the available space into three (horizontally), and places text centered in the first two cells and the Flutter logo centered in the third:

new Row(
  children: <Widget>[
    new Expanded(
      child: new Text('Deliver features faster', textAlign: TextAlign.center),
    ),
    new Expanded(
      child: new Text('Craft beautiful UIs', textAlign: TextAlign.center),
    ),
    new Expanded(
      child: new FittedBox(
        fit: BoxFit.contain, // otherwise the logo will be tiny
        child: const FlutterLogo(),
      ),
    ),
  ],
)

Troubleshooting

Why is my row turning red?

If the contents of the row overflow, meaning that together they are wider than the row, then the row runs out of space to give its Expanded and Flexible children, and reports this by drawing a red warning box on the edge that is overflowing.

Story time

Suppose, for instance, that you had this code:

new Row(
  children: <Widget>[
    const FlutterLogo(),
    const Text('Flutter\'s hot reload helps you quickly and easily experiment, build UIs, add features, and fix bug faster. Experience sub-second reload times, without losing state, on emulators, simulators, and hardware for iOS and Android.'),
    const Icon(Icons.sentiment_very_satisfied),
  ],
)

The row first asks its first child, the FlutterLogo, to lay out, at whatever size the logo would like. The logo is friendly and happily decides to be 24 pixels to a side. This leaves lots of room for the next child. The row then asks that next child, the text, to lay out, at whatever size it thinks is best.

At this point, the text, not knowing how wide is too wide, says "Ok, I will be thiiiiiiiiiiiiiiiiiiiis wide.", and goes well beyond the space that the row has available, not wrapping. The row responds, "That's not fair, now I have no more room available for my other children!", and gets angry and turns red.

The fix is to wrap the second child in an Expanded widget, which tells the row that the child should be given the remaining room:

new Row(
  children: <Widget>[
    const FlutterLogo(),
    const Expanded(
      child: const Text('Flutter\'s hot reload helps you quickly and easily experiment, build UIs, add features, and fix bug faster. Experience sub-second reload times, without losing state, on emulators, simulators, and hardware for iOS and Android.'),
    ),
    const Icon(Icons.sentiment_very_satisfied),
  ],
)

Now, the row first asks the logo to lay out, and then asks the icon to lay out. The Icon, like the logo, is happy to take on a reasonable size (also 24 pixels, not coincidentally, since both FlutterLogo and Icon honor the ambient IconTheme). This leaves some room left over, and now the row tells the text exactly how wide to be: the exact width of the remaining space. The text, now happy to comply to a reasonable request, wraps the text within that width, and you end up with a paragraph split over several lines.

Layout algorithm

This section describes how a Row is rendered by the framework. See BoxConstraints for an introduction to box layout models.

Layout for a Row proceeds in six steps:

  1. Layout each child a null or zero flex factor (e.g., those that are not Expanded) with unbounded horizontal constraints and the incoming vertical constraints. If the crossAxisAlignment is CrossAxisAlignment.stretch, instead use tight vertical constraints that match the incoming max height.
  2. Divide the remaining horizontal space among the children with non-zero flex factors (e.g., those that are Expanded) according to their flex factor. For example, a child with a flex factor of 2.0 will receive twice the amount of horizontal space as a child with a flex factor of 1.0.
  3. Layout each of the remaining children with the same vertical constraints as in step 1, but instead of using unbounded horizontal constraints, use horizontal constraints based on the amount of space allocated in step 2. Children with Flexible.fit properties that are FlexFit.tight are given tight constraints (i.e., forced to fill the allocated space), and children with Flexible.fit properties that are FlexFit.loose are given loose constraints (i.e., not forced to fill the allocated space).
  4. The height of the Row is the maximum height of the children (which will always satisfy the incoming vertical constraints).
  5. The width of the Row is determined by the mainAxisSize property. If the mainAxisSize property is MainAxisSize.max, then the width of the Row is the max width of the incoming constraints. If the mainAxisSize property is MainAxisSize.min, then the width of the Row is the sum of widths of the children (subject to the incoming constraints).
  6. Determine the position for each child according to the mainAxisAlignment and the crossAxisAlignment. For example, if the mainAxisAlignment is MainAxisAlignment.spaceBetween, any horizontal space that has not been allocated to children is divided evenly and placed between the children.

See also:

  • Column, for a vertical equivalent.
  • Flex, if you don't know in advance if you want a horizontal or vertical arrangement.
  • Expanded, to indicate children that should take all the remaining room.
  • Flexible, to indicate children that should share the remaining room but that may by sized smaller (leaving some remaining room unused).
Inheritance

Constructors

Row({Key key, MainAxisAlignment mainAxisAlignment: MainAxisAlignment.start, MainAxisSize mainAxisSize: MainAxisSize.max, CrossAxisAlignment crossAxisAlignment: CrossAxisAlignment.center, TextBaseline textBaseline, List<Widget> children: const [] })
Creates a horizontal array of children. [...]

Properties

children List<Widget>
The widgets below this widget in the tree. [...]
final, inherited
crossAxisAlignment CrossAxisAlignment
How the children should be placed along the cross axis. [...]
final, inherited
direction Axis
The direction to use as the main axis. [...]
final, inherited
hashCode int
The hash code for this object. [...]
read-only, inherited
key Key
Controls how one widget replaces another widget in the tree. [...]
final, inherited
mainAxisAlignment MainAxisAlignment
How the children should be placed along the main axis. [...]
final, inherited
mainAxisSize MainAxisSize
How much space should be occupied in the main axis. [...]
final, inherited
runtimeType Type
A representation of the runtime type of the object.
read-only, inherited
textBaseline TextBaseline
If aligning items according to their baseline, which baseline to use.
final, inherited

Methods

createElement() MultiChildRenderObjectElement
RenderObjectWidgets always inflate to a RenderObjectElement subclass.
inherited
createRenderObject(BuildContext context) RenderFlex
Creates an instance of the RenderObject class that this RenderObjectWidget represents, using the configuration described by this RenderObjectWidget. [...]
inherited
debugFillDescription(List<String> description) → void
Add additional information to the given description for use by toString. [...]
@mustCallSuper, @protected, inherited
didUnmountRenderObject(RenderObject renderObject) → void
A render object previously associated with this widget has been removed from the tree. The given RenderObject will be of the same type as returned by this object's createRenderObject.
@protected, inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a non-existent method or property is accessed. [...]
inherited
toString() String
Returns a string representation of this object.
inherited
toStringShort() String
A short, textual description of this widget.
inherited
updateRenderObject(BuildContext context, RenderFlex renderObject) → void
Copies the configuration described by this RenderObjectWidget to the given RenderObject, which will be of the same type as returned by this object's createRenderObject. [...]
inherited

Operators

operator ==(other) bool
The equality operator. [...]
inherited