flutter - correct way to create a box that starts at minHeight, grows to maxHeight

DartFlutter

Dart Problem Overview


I have a container that I want to start off at a minimum size and grow (if its contents grow while user is adding content) to a maximum size, then stop.

The correct widget for this seems to be ConstrainedBox, like so:

new ConstrainedBox(
  constraints: new BoxConstraints(
    minHeight: 35.0,
    maxHeight: 60.0,
  ),
  child: ...child with growing content (has default height 25.0)...
),

however, this starts the box off at the maxHeight.

I tried to use hasBoundedHeight, but can not seem to construct the correct syntax for it or find an example in documentation.

What is the best way to get the box working as described?

Dart Solutions


Solution 1 - Dart

There's no notion of "Starts from max/min size".

The thing is, ContrainedBox only add constraints to it's child. But in the end, it doesn't pick a size.

If you want your child to hit minSize, then they have to not expend. Which translate into not having a width/height of double.INFINITY. Fact is that double.INFINITY is the default value of many widgets, including Container.

On the other hand, some widgets such as DecoratedBox have a default size of 0. Which means that this code :

return new ConstrainedBox(
  constraints: new BoxConstraints(
    minHeight: 5.0,
    minWidth: 5.0,
    maxHeight: 30.0,
    maxWidth: 30.0,
  ),
  child: new DecoratedBox(
    decoration: new BoxDecoration(color: Colors.red),
  ),
);

Will render a 5.0*5.0 red square.

Solution 2 - Dart

Below Example will help you to grow Size of the widget as required

Container(
          color: Colors.blueAccent,
          constraints: BoxConstraints(
              minHeight: 100, minWidth: double.infinity, maxHeight: 400),
          child: ListView(
            shrinkWrap: true,
            children: <Widget>[
              ...List.generate(
                10,  // Replace this with 1, 2 to see min height works. 
                (index) => Text(
                  'Sample Test: ${index}',
                  style: TextStyle(fontSize: 60, color: Colors.black),
                ),
              ),
            ],
          ),
        ),

Output for Min Height for Single Item:

enter image description here

Output for Min Height for 10 Items:

enter image description here

Note: This will show widgets as per mentioned max-height.

Blog: https://medium.com/flutterworld/flutter-how-to-set-the-minimum-height-to-widget-36967b310ffe

Solution 3 - Dart

You can use deviceWidth and deviceHeight to check for min and max condition. Use the following code to get the deviceWidth and deviceHeight in build method.

double deviceWidth = MediaQuery.of(context).size.width;
double deviceHeight = MediaQuery.of(context).size.height;

In width and height property of Container use deviceWidth and deviceHeight to form your condition.

Container(
width: deviceWidth<200?50:deviceWidth*0.5,
height: deviceHeight<500?50:deviceHeight>800?200:deviceHeight*0.2,
child: //child,
)

Note: Only Ternary Operator ?: works for specifying condition for height and width

Solution 4 - Dart

Yes, ConstrainedBox is the right widget for the purpose. If you'll give only minHeight parameter for eg. 300, the child will be of minimum height and will increase its size according to its content.

Here's an example:

ConstrainedBox(
   constraints: BoxConstraints(
       minHeight: 300,
       ),
   child: Container(child : SomeWidget(),)

If height required by SomeWidget() is less than 300, it will be of height 300. Otherwise, it will increase it's height accordingly. For decoration and structuring your SomeWidget(), you can use padding and other properties of Container.

Solution 5 - Dart

enter image description here

ConstrainedBox(
   constraints: BoxConstraints(
      minWidth: 70, 
      minHeight: 70,
      maxWidth: 150, 
      maxHeight: 150,
   ),
   child: Container(color: Colors.red, width: 10, height: 10),
)

You might guess that the Container has to be between 70 and 150 pixels, but you would be wrong. The ConstrainedBox only imposes additional constraints from those it receives from its parent.

Here, the screen forces the ConstrainedBox to be exactly the same size as the screen, so it tells its child Container to also assume the size of the screen, thus ignoring its constraints parameter.

Solution 6 - Dart

For Column for example, minHeight is not working. I solved it using this hack:

ConstrainedBox(
  constraints: BoxConstraints(minHeight: 150),
  child: Stack(
	children: [
	  Column(
		children: [dynamicChild1, dynamicChild2],
	  ),
	],
  ),
);

So, just by wrapping Column in Stack. Now the Column size became 150 and more.

Solution 7 - Dart

As Remi's answer points out, if your ConstrainedBox is initially maxing out a dimension when you expected it to be closer to or at the min, it's because a child wants to be big. (Re: Constraints go down. Sizes go up. Parent sets position.) If you aren't sure which child is causing it, one handy way is to use the Widget Inspector in your IDE and check the properties of the descendants, then check the docs as to why and adjust accordingly.

For example, I've run into this e.g. when wrapping a widget in Center. Normally without constraints the centered widget would match the child's height. However, when putting the Center inside a ConstrainedBox, all of a sudden it blew up to the max constraints. After checking the docs, I saw that:

  1. This widget will be as big as possible if its dimensions are constrained and widthFactor and heightFactor are null, explaining the new layout.
  2. But: If a dimension is unconstrained and the corresponding size factor is null then the widget will match its child's size in that dimension, which explains the behavior without the ConstrainedBox.
  3. And this tells me how to fix it: If a size factor is non-null then the corresponding dimension of this widget will be the product of the child's dimension and the size factor, i.e. set the Center's heightFactor: 1.

So pay attention to how your children behave! If you impose external constraints, they may be greedy (or not, just like real kids ;).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDeborahView Question on Stackoverflow
Solution 1 - DartRémi RousseletView Answer on Stackoverflow
Solution 2 - DartJitesh MohiteView Answer on Stackoverflow
Solution 3 - DartFirosh VasudevanView Answer on Stackoverflow
Solution 4 - DartK Y MView Answer on Stackoverflow
Solution 5 - DartParesh MangukiyaView Answer on Stackoverflow
Solution 6 - DartRodion MostovoyView Answer on Stackoverflow
Solution 7 - DartqixView Answer on Stackoverflow