flutterlistviewflutter-renderflex-error

Horizontal ListView doesn't show children with no fixed width


I'm trying to replicate this design: image

These 3 are progress indicators and their number is dynamic. That's why I thought of creating a list view and populating it depending on their number. Plus their size should NOT be fixed and they must, as a group, fill the size of the screen but this isn't happening.

Container(
                          height: 10,
                          width: 400,
                          child: ListView.builder(
                            physics: NeverScrollableScrollPhysics(),
                            scrollDirection: Axis.horizontal,
                            shrinkWrap: true,
                            itemCount: 3,
                            itemBuilder: (BuildContext context, int index) {
                              return Container(
                                child: LinearPercentIndicator(
                                    padding: index == 0 ? EdgeInsets.only(right: 4.0, left: 2.0) : EdgeInsets.symmetric(horizontal: 4.0),
                                    alignment: MainAxisAlignment.start,
                                    lineHeight: 5.0,
                                    percent: 1.0,
                                    progressColor: index == 2 ? theme.inboxListItemShadowColor : theme.userProfileTierBadgeColor,
                                    backgroundColor: theme.inboxListItemShadowColor,
                                    barRadius: Radius.circular(50)
                                ),
                              );
                            },
                          ),
                        )

And I thought this might create the design I needed but it always generates the error below:

RenderFlex children have non-zero flex but incoming width constraints are unbounded.

And that's because the Container widget containing the LinearPercentIndicator has no fixed width. And I don't want fixed width cause it won't support different screens.

So any idea on how I might do this? All i need is to have the children of the list view have dynamic widths depending on the screen and all fit in it.

Tried to give each container width like this:

width: (MediaQuery.of(context).size.width - 30) / n,

Where n is the number of progress indicators to create but it always messes up the design.


Solution

  • The issue is LinearPercentIndicator is trying to get as much width as possible and horizontal ListView provides infinite width(you can think this way). You can provide fixed 1/3 screen width. for as for the ui, Row is enough.

    Row(
      children: [
        for (int i = 0; i < 3; i++)
          Expanded(
            child: LinearPercentIndicator(
                padding: i == 0
                    ? EdgeInsets.only(right: 4.0, left: 2.0)
                    : EdgeInsets.symmetric(horizontal: 4.0),
                alignment: MainAxisAlignment.start,
                lineHeight: 5.0,
                percent: 1.0,
                barRadius: Radius.circular(50)),
          ),
      ],
    ),
    

    Using fixed width

    Container(
      height: 10,
      width: 400,
      child: ListView.builder(
        physics: NeverScrollableScrollPhysics(),
        scrollDirection: Axis.horizontal,
        shrinkWrap: true,
        itemCount: 3,
        itemBuilder: (BuildContext context, int index) {
          return Container(
            width: 400 / 3, //400 was your top widget width
            child: LinearPercentIndicator(
                padding: index == 0
                    ? EdgeInsets.only(right: 4.0, left: 2.0)
                    : EdgeInsets.symmetric(horizontal: 4.0),
                alignment: MainAxisAlignment.start,
                lineHeight: 5.0,
                percent: 1.0,
                barRadius: Radius.circular(50)),
          );
        },
      ),
    )