Jonas
Jonas

Reputation: 7945

Flutter expand Row inside ListView

I want to use a Row inside a horizontally scrolling list. When there are only few children in the row, the row should take up the full with and apply mainAxisAlignment: MainAxisAlignment.spaceEvenly such that it looks like this:

enter image description here

However when there are a lot of items, such that it doesn't fully fit on the screen, the row should be scrollable.

I currently have this code:

    Container(
      height: 40,
      child: ListView(
        scrollDirection: Axis.horizontal,
        children: <Widget>[
          Row(
            mainAxisSize: MainAxisSize.max,
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              Container(
                width: 100,
                height: 40,
                color: Colors.red
              ),
              Container(
                width: 100,
                height: 40,
                color: Colors.blue
              ),
              
            ],
          ),
        ],
      ),
    ),

However the Row's width is only as wide as the children's combined with, such that it doesn't apply mainAxisAlignment: MainAxisAlignment.spaceEvenly. So it looks like this:

enter image description here

Is there a good way to achieve this in Flutter? So I need to expand the Row to atlest the full ListView with but also allow it to go larger.

Upvotes: 4

Views: 1444

Answers (1)

Hossein Yousefi
Hossein Yousefi

Reputation: 1031

We can use a LayoutBuilder to understand the constraints of our viewport. Inside we can return a SingleChildScrollView to apply the scrolling effects. Now we want the minimum width of our row to be the same as the maximum amount of width we have, here we can use a ConstrainedBox to add an extra minWidth constraint to our row:

LayoutBuilder(
  builder: (BuildContext context, BoxConstraints viewportConstraints) {
    return SingleChildScrollView(
      scrollDirection: Axis.horizontal,
      child: ConstrainedBox(
        constraints: BoxConstraints(
          minWidth: viewportConstraints.maxWidth,
        ),
        child: Row(
          mainAxisSize: MainAxisSize.min,
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            Container(width: 100, height: 40, color: Colors.red),
            Container(width: 100, height: 40, color: Colors.blue),
          ],
        ),
      ),
    );
  },
),

Notice how we're using MainAxisSize.min because we want the row to use as little width as it can but it's constrained by the minWidth we provided to the ConstrainedBox.

Result:

before

When they don't fit:

after

Upvotes: 3

Related Questions