Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 559
TommyF Avatar asked Jul 13 '18 13:07

TommyF


People also ask

How do you set the height and width of a Row in Flutter?

Change width of a row Row normally takes available space and we can control that by wrapping inside a Container or SizedBox widget. You can wrap the Row inside the Container and add width to the container. Then the Row will take the same width as a Container.

What is the best way to give space in Row and Column in Flutter?

Using MainAxisAlignment (Recommended) Using the MainAxisAlignment property of Column and Row, you can add the predefined space between the widgets. If you use the MainAxisAlignment property, you don't need to add any extra widgets in between the widgets.

How do I stretch widgets in Flutter?

center, children: <Widget>[ Expanded( child: SizedBox( width: double. infinity, child: FlatButton( onPressed: () { playSound(1); }, color: Colors. blue, ), ), ), Expanded widget will share the height while the SizedBox widget will take up the whole width with width is set to double.


3 Answers

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

like image 184
Matt S. Avatar answered Oct 10 '22 22:10

Matt S.


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'),
          )),
    ]),
  ]),
like image 4
oblomov Avatar answered Oct 10 '22 21:10

oblomov


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:

SizedBox(
 height: 100,
 child: Row(
 crossAxisAlignment: CrossAxisAlignment.stretch,
 children: [
  Expanded(
    child: Column(
      children: [
        Expanded( //If you dont 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,
    ),
   )
  ],
 ),
),
like image 3
Daniel Valencia Avatar answered Oct 10 '22 23:10

Daniel Valencia