1

I have a Column with some widgets, and I want the last one of those widgets to be at most 100px tall, but if there's not enough room on the screen then it should be able to shrink down to 0px.

So if this is my layout, I want the part below the black square to be at most 100px, but if the screen is too small I want it to shrink accordingly.

      Center(
        child: Container(
          height: double.infinity,
          width: double.infinity,
          color: Colors.blue,
          child: Column(
            children: <Widget>[
              SizedBox(height: 20),
              Container(color: Colors.white, width: 200, height: 200),
              SizedBox(height: 20),
              Container(color: Colors.grey, width: 400, height: 100),
              Expanded(child: SizedBox(height: double.infinity)),
              SizedBox(height: 50),
              Container(color: Colors.black, width: 200, height: 200),
              SizedBox(height: 100),
            ],
          ),
        ),
      );

Notice the Expanded in the middle - this makes the distance between the grey and black containers adjust to fill the screen height. The problem is that some devices have a screen that is so small that this Expanded becomes 0px, and then the bottom SizedBox will overflow. Hence why I want it to adjust, but never become taller than 100px.

Even after reading through the documentation about constraints, I still don't know how to achieve this.

Magnus
  • 17,157
  • 19
  • 104
  • 189

2 Answers2

0

Answering your question, to give it a maximum height you can try to use a Constrained Box:

ConstrainedBox(
    constraints: BoxConstraints(maxHeight: 100),
    child: SizedBox(height: 100),
)

This will make the SizedBox never be able to be more than 100 pixels tall.

However, to achieve your desired behaviour you can use the Flexible Widget:

Flexible(
  child: SizedBox(height: 100),
);

Remember that Flexible works like Expanded but it uses as default FlexFit the value of FlexFit.loose, so its child is allowed to be smaller than the available space. This way it won't enforce your SizedBox to be bigger than it is supposed to.

Naslausky
  • 3,443
  • 1
  • 14
  • 24
  • Unfortunately, neither of these solutions seem to work. Using `ConstrainedBox`, the overflow still happens just as before. Using `Flexible`, the overflow goes away, but the space grows larger than the desired 100px when the screen is big enough. – Magnus Sep 15 '20 at 13:19
  • @MagnusW How are you verifying that? In my tests using DartPad and giving the SizedBox a background color, it did not went larger than 100px. – Naslausky Sep 15 '20 at 14:12
  • I tried it both on a real device and on Dartpad, and I'm getting the same results on both. `Flexible` makes the bottom spacing grow bigger than 100px, `ConstrainedBox` results in overflow. I'm wrapping it in a `MaterialApp` and `Scaffold`. The `SizedBox` might not grow bigger than 100px, but the spacing below the black box does, which is what I want to prevent. – Magnus Sep 15 '20 at 14:37
  • @MagnusW Try adding the property ```mainAxisSize: MainAxisSize.min,``` to your Collumn. Is that the result you want? – Naslausky Sep 15 '20 at 14:46
  • Unfortunately no. The result I want is that the black container should be 100px from the bottom of the screen, except that if the screen is too small, then the distance to the bottom would be less. Effectively that's what I have now, but there's an overflow error because the bottom `SizedBox` is going down off the screen instead of shrinking when the screen is too small. – Magnus Sep 15 '20 at 18:01
0

Well the best way is using MediaQuery it can also give you responsive layout.

Pradana
  • 51
  • 4