3

I have a Row where the children are Expanded widgets. My goal is to wrap this Row (like with Wrap) if there is not enough space for all children.

I already tried to replace Row by Wrap:

return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Wrap(
          children: [
            Expanded(
              child: element("Sun Glasses"),
            ),
          ],
        )
      ),
    );

but this lead to the error:

The following assertion was thrown while applying parent data.:
Incorrect use of ParentDataWidget.

The ParentDataWidget Expanded(flex: 1) wants to apply ParentData of type FlexParentData to a RenderObject, which has been set up to accept ParentData of incompatible type WrapParentData.

Usually, this means that the Expanded widget has the wrong ancestor RenderObjectWidget. Typically, Expanded widgets are placed directly inside Flex widgets.
The offending Expanded is currently placed inside a Wrap widget.

Since it is important that the elements of a row fill it up, I cannot simply remove Expanded. Is there a way to achieve this?

This is the Mockup that I am trying to implement:

enter image description here

Jozott
  • 2,367
  • 2
  • 14
  • 28
  • could you add the parent of Wrap? – eamirho3ein Oct 23 '22 at 10:54
  • @eamirho3ein did it – Jozott Oct 23 '22 at 10:57
  • What do you want exactly? You need a wrap that splits widgets into lines and fills only last line? – amir_a14 Oct 23 '22 at 12:28
  • @amir_a14 The behaviour should be the following: fill the row with as many elements as possible and fill the space left by adding padding to the items in that row. Then go to the next row and fill it up with the next elements, and do the same again. So as you can see in the mockup, each row should fill the whole width, and in one row there should be as many elements as possible. – Jozott Oct 23 '22 at 12:47
  • "After all the children have been allocated to runs, the children within the runs are positioned according to the alignment in the main axis and according to the crossAxisAlignment in the cross axis." Just need to set those properly. – Randal Schwartz Oct 23 '22 at 16:17
  • @Randal Schwartz the problem is, that the items need to expand to the full width of the row. Wrap doesn't support that since all items keep their size. I built a custom widget (custom renderbox) for this purpose, since I couldn't find any solution. – Jozott Oct 26 '22 at 07:06

1 Answers1

9

Since I couldn't find any existing solution for this problem, I wrote a custom RenderBox widget.

You can find the source code on Github and the flutter package on pub.dev.

Simple Example with FlexList

SizedBox(
    width: 300,
    child: FlexList(
      horizontalSpacing: 5,
      verticalSpacing: 10,
      children: [
        for (var i = 0; i < 10; i++)
          Container(
            color: Theme
                .of(context)
                .backgroundColor,
            padding: EdgeInsets.symmetric(
                horizontal: 20 + 20 * (i % 4), vertical: 10),
            child: Text("Item $i"),
          )
      ],
    )),

Example Rendering

Jozott
  • 2,367
  • 2
  • 14
  • 28