Guster
Guster

Reputation: 1821

How to make a widget fill remaining space in a Column

In Android, we can do the following to make ImageView to fill as much space as possible depending on the size of the TextView.

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_weight="1"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>

How do we achieve this in Flutter? Assume I need to make Datetime(green) to fill as much as possible.

new Column(
    children: <Widget>[
        new Text('Title',
            style: new TextStyle(fontWeight: FontWeight.bold)
        ),
        new Text('Datetime',
            style: new TextStyle(color: Colors.grey)
        ),
    ],
)

enter image description here

Upvotes: 84

Views: 126786

Answers (7)

Ahmad Abdullah
Ahmad Abdullah

Reputation: 141

The Flexible widget helps adjust the size of its child to the exsiting space, but note if you use it in a listview or singelchild scrollview it may create problems

Flexible(
      child: Column(
        mainAxisAlignment:MainAxisAlignment.spaceBetween,
        children: <Widget>[
            new Text('Title',
                style: new TextStyle(fontWeight: FontWeight.bold)
            ),
            new Text('Datetime',
                style: new TextStyle(color: Colors.grey)
            ),
      ],
    ),

Upvotes: 4

Fredrik_Borgstrom
Fredrik_Borgstrom

Reputation: 3218

  1. Wrap the child of your Flex/Row/Column container that should be as small as possible in a Flexible widget and set it's fit property to FlexFit.loose and it's flex property to 0.
  2. Wrap the child that should fill up the remaining space in an Expanded widget (this is the equivalent of wrapping it in a Flexible widget and set it's fit property to FlexFit.tight).

Applying this to your code, where 'Title' should only occupy the minimum necessary space and 'Datetime' should fill up the remaining space:

Column(
    children: [
        Flexible (
          fit: FlexFit.loose,
          flex: 0,
          child: Text ('Title', style: TextStyle(fontWeight: FontWeight.bold))
        ),
        Expanded(
          child: Text('Datetime', style: TextStyle(color: Colors.grey)),
        ),
    ],
)

Upvotes: 1

Victor Batista
Victor Batista

Reputation: 15

You must give a height to the Row, so its children knows the avaliable space. You can do it wrapping the Row with an IntrinsicHeight Widget;

Upvotes: 1

Ali Izadyar
Ali Izadyar

Reputation: 220

This is how it worked in my case:

IntrinsicHeight(
      child: Row(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Flexible(
              child: Image.memory(
                File('path').readAsBytesSync(),
                width: 150,
                height: 150,
              ),
              flex: 5,
            ),
            Flexible(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Text('Title',
                      style: TextStyle(fontWeight: FontWeight.bold)
                  ),
                  Text('Datetime',
                      style: TextStyle(color: Colors.grey)
                  ),
                ],
              ),
              flex: 1,
            ),
          ]),
    ),

Upvotes: 1

CopsOnRoad
CopsOnRoad

Reputation: 267404

You can use:

  1. Expanded with Align to position child

    Column(
      children: [
        FlutterLogo(),
        Expanded( // add this
          child: Align(
            alignment: Alignment.bottomCenter,
            child: FlutterLogo(),
          ),
        ),
      ],
    )
    
  2. Spacer

    Column(
      children: [
        FlutterLogo(),
        Spacer(), // add this
        FlutterLogo(),
      ],
    )
    
  3. mainAxisAlignment

    Column(
      mainAxisAlignment: MainAxisAlignment.spaceBetween, // add this
      children: [
        FlutterLogo(colors: Colors.orange),
        FlutterLogo(colors: Colors.blue),
      ],
    )
    

Upvotes: 32

Vadim Osovsky
Vadim Osovsky

Reputation: 905

If you need just to add blank space, use Spacer()

new Column(
children: <Widget>[
    new Text('Title',
        style: new TextStyle(fontWeight: FontWeight.bold)
    ),
    new Text('Datetime',
        style: new TextStyle(color: Colors.grey)
    ),
    Spacer(),
],

Upvotes: 13

Kevin Walter
Kevin Walter

Reputation: 7166

Not 100% sure but I think you mean this. The Expanded widget expands to the space it can use. Althought I think it behaves a bit differently in a Row or Column.

new Column(
children: <Widget>[
    new Text('Title',
        style: new TextStyle(fontWeight: FontWeight.bold)
    ),
    new Expanded(
        child: new Text('Datetime',
             style: new TextStyle(color: Colors.grey)
        ),
    ),
],
)

Upvotes: 149

Related Questions