TommyF
TommyF

Reputation: 7140

Flutter Layout Row / Column - share width, expand height

I'm still having a bit of trouble with the layouting in Flutter.
Right now I want to have the available space shared between 3 widgets, in a quadrant layout. The width is evenly shared (this works fine via 2 Expanded widgets in a Row), but now I also want the height to adjust automatically so widget3.height == widget1.height + widget2.height. layout If the content of widget3 is larger, I want widget1 and widget2 to adjust their height and vice versa.

Is this even possible in Flutter?

Upvotes: 135

Views: 287739

Answers (5)

Daniel Valencia
Daniel Valencia

Reputation: 605

I think that you can set the height of the row instead, then you only must to set the height of you column containers, and with the crossAxisAlignment: CrossAxisAlignment.stretch the second row will be expand occupying his parent height:

Row(
  crossAxisAlignment: CrossAxisAlignment.stretch,
  children: [
    Expanded(
      child: Column(
        children: [
          Expanded(
            // If you don't have the height you can expanded with flex
            flex: 1,
            child: Container(
              height: 50,
              color: Colors.blue,
            ),
          ),
          Expanded(
            flex: 1,
            child: Container(
              height: 50,
              color: Colors.red,
            ),
          )
        ],
      ),
    ),
    Expanded(
      child: Container(
        color: Colors.yellow,
      ),
    )
  ],
)

Upvotes: 11

Manish garg
Manish garg

Reputation: 1

if you have used the expanded inside Row and facing for full height issue then just wrap the expanded child with Align widget.

Upvotes: -2

Amrit Mishra
Amrit Mishra

Reputation: 35

I'm new to flutter. Please correct me if I'm doing something wrong here. I think It can also be achieved using setState((){}) without using IntrinsicHeight.

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return MyAppState();
  }
}

class MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    double h1 = 100;
    double h2 = 200;
    double h3;
    setState(() {
      h3 = h1 + h2;
    });
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: Padding(
            padding: const EdgeInsets.only(top: 100.0),
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Expanded(
                  child: Column(
                    children: [
                      Container(
                        color: Colors.green,
                        height: h1,
                      ),
                      Container(
                        color: Colors.orange,
                        height: h2,
                      )
                    ],
                  ),
                ),
                Expanded(
                  child: Container(
                    color: Colors.yellow,
                    height: h3,
                  ),
                )
              ],
            ),
          ),
        ),
      ),
    );
  }
}

Find image here

Code can also be found here: https://gist.github.com/Amrit0786/9d228017c2df6cf277fbbaa4a6b20e83

Upvotes: 1

oblomov
oblomov

Reputation: 544

Since IntrinsicHeight is considered relatively expensive, it's better to avoid it. You can use Table with verticalAlignment: TableCellVerticalAlignment.fill in the largest TableCell.

Please note that if you use .fill in all cells, the TableRow will have zero height.

  Table(children: [
    TableRow(children: [
      Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Container(
            alignment: Alignment.center,
            color: Colors.blue,
            child: Text('Widget 1'),
          ),
          Container(
            alignment: Alignment.center,
            color: Colors.green,
            child: Text('Widget 2'),
          ),
        ],
      ),
      TableCell(
          verticalAlignment: TableCellVerticalAlignment.fill,
          child: Container(
            alignment: Alignment.center,
            color: Colors.orange,
            child: Text('Widget 3'),
          )),
    ]),
  ]),

Upvotes: 13

Matt S.
Matt S.

Reputation: 10462

Have a look at IntrinsicHeight; wrapping the root Row should provide the effect you're looking for:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(title: Text('Rows & Columns')),
        body: RowsAndColumns(),
      ),
    );
  }
}

class RowsAndColumns extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(top: 100.0),
      child: IntrinsicHeight(
        child: Row(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
          Expanded(
            child: Column(children: [
              Container(height: 120.0, color: Colors.yellow),
              Container(height: 100.0, color: Colors.cyan),
            ]),
          ),
          Expanded(child: Container(color: Colors.amber)),
        ]),
      ),
    );
  }
}

Adjusting the heights in the containers in the column cause the container on the right to resize to match:

screenshot

https://gist.github.com/mjohnsullivan/c5b661d7b3b4ca00599e8ef87ff6ac61

Upvotes: 393

Related Questions