Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using FractionallySizedBox in a Row

Tags:

flutter

I want to have a widget of arbitrary width that contains a row of three widgets sized relatively to its parent.

FractionallySizedBox sounds like the right tool for the job, so I tried it like this:

Container(height: 24.0, color: Colors.black, child:
  Row(children: [
    FractionallySizedBox(heightFactor: 1, widthFactor: 0.25,
                         child: Container(color: Colors.orange)),
    FractionallySizedBox(heightFactor: 1, widthFactor: 0.15,
                         child: Container(color: Colors.green)),
    FractionallySizedBox(heightFactor: 1, widthFactor: 0.05,
                         child: Container(color: Colors.blue)),
  ]
)

But I'm getting an error

BoxConstraints forces an infinite width.

This happens even when I set some width on the enclosing container.

Why doesn't this work?

like image 718
HoiPolloi Avatar asked Jul 28 '19 16:07

HoiPolloi


2 Answers

As explained in the "FractionallySizedBox (Flutter Widget of the Week)" video by the Flutter team, the FractionallySizedBox needs to be wrapped in Flexible widget, "so it plays well with a row or a column".

Reference: https://www.youtube.com/watch?v=PEsY654EGZ0

This should be the solution to the original question, formatted below:

Container(
    height: 24.0, 
    color: Colors.black, 
    child: Row(
        children: [
            Flexible(
                child: FractionallySizedBox(
                    heightFactor: 1, widthFactor: 0.25,
                    child: Container(color: Colors.orange),
                ),
            ),
            Flexible(
                child: FractionallySizedBox(
                    heightFactor: 1, widthFactor: 0.15,
                    child: Container(color: Colors.green)),
            ),
            Flexible(
                child: FractionallySizedBox(
                    heightFactor: 1, widthFactor: 0.05,
                    child: Container(color: Colors.blue)
                ),
            ),
        ]
    )
)

I have also worked on something similar and was looking for a solution to the problem, this is my code for representing data levels:

Row(
    children: <Widget>[
      Flexible(
        child: FractionallySizedBox(
            widthFactor: 1,
            child: Container(
              margin: EdgeInsets.only(right: 5),
              height: 6,
              decoration: BoxDecoration(
                  color: Colors.blue,
                  borderRadius: BorderRadius.all(Radius.circular(125)),
              ),
            )
        ),
      ),
      Flexible(
        child: FractionallySizedBox(
            widthFactor: 1,
            child: Container(
              margin: EdgeInsets.only(right: 5),
              height: 6,
              decoration: BoxDecoration(
                color: Colors.blue,
                borderRadius: BorderRadius.all(Radius.circular(125)),
              ),
            )
        ),
      ),
      Flexible(
        child: FractionallySizedBox(
            widthFactor: 1,
            child: Container(
              margin: EdgeInsets.only(right: 5),
              height: 6,
              decoration: BoxDecoration(
                color: Colors.blue,
                borderRadius: BorderRadius.all(Radius.circular(125)),
              ),
            )
        ),
      ),
      Flexible(
        child: FractionallySizedBox(
            widthFactor: 1,
            child: Container(
              margin: EdgeInsets.only(right: 5),
              height: 6,
              decoration: BoxDecoration(
                color: Colors.blue,
                borderRadius: BorderRadius.all(Radius.circular(125)),
              ),
            )
        ),
      ),
      Flexible(
        child: FractionallySizedBox(
            widthFactor: 1,
            child: Container(
              margin: EdgeInsets.only(right: 5),
              height: 6,
              decoration: BoxDecoration(
                color: Colors.blue,
                borderRadius: BorderRadius.all(Radius.circular(125)),
              ),
            )
        ),
      ),
    ],
),

Resulting in: evenly spaced bars

like image 107
k dimitrov Avatar answered Sep 19 '22 07:09

k dimitrov


You can't use FractionallySizedBox in Row or Column directly. You can split as percent Row and Column use flex parameter of Expand widget like below.

Row(
      children: <Widget>[
        Expanded(
          flex: 6, // 60% of space => (6/(6 + 4))
          child: Container(
            color: Colors.red,
          ),
        ),
        Expanded(
          flex: 4, // 40% of space
          child: Container(
            color: Colors.purple,
          ),
        ),
      ],
    ),
like image 40
Savas Adar Avatar answered Sep 20 '22 07:09

Savas Adar