proninyaroslav
proninyaroslav

Reputation: 772

How to fill a widget to the full available Row height

The layout looks like this: Layout

Here is a Row, which is inside ListView. Inside it's a Column with Text widgets, leading and trailing widgets. The problem is that the leading widget has to fill the free height of the Row. The Row height is determined by the Column with the Text widgets, and the leading widget should adjust to this size and not try to increase the Row height to infinity (for example, the leading widget can be a colored Container with infinite height and given width). Is it possible to do this?

Upvotes: 14

Views: 21052

Answers (3)

Thierry
Thierry

Reputation: 8383

enter image description here

Use crossAxisAlignment: CrossAxisAlignment.stretch to fill the height of a Row (width of a Column), i.e. to stretch along the CrossAxis.

Use Expanded widgets to fill the space along the MainAxis The flex attributes will determine the proportion of each widget.

For the trailing widget, just use a Center widget to center it.

In order to have your Row inside a ListView, stretching to the height of the tallest child, put the Row inside an IntrinsicHeight widget.

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Row and Column',
      home: Scaffold(
        body: ListView(
          children: [
            IntrinsicHeight(
              child: Row(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: [
                  Expanded(child: MyWidget()),
                  Expanded(
                    flex: 3,
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.stretch,
                      children: [
                        MyTextWidget(
                          text:
                              'I like to believe that science is becoming mainstream.',
                        ),
                        MyTextWidget(
                          text:
                              'There is no known objects accounting for most of the effective gravity in the universe.',
                        ),
                        MyTextWidget(
                          text: "Let's explore because it's fun.",
                        ),
                      ],
                    ),
                  ),
                  Expanded(
                    child: Center(
                      child: SizedBox(height: 40.0, child: MyWidget()),
                    ),
                  ),
                ],
              ),
            ),
            Spacer(),
          ],
        ),
      ),
    ),
  );
}

class MyTextWidget extends StatelessWidget {
  final String text;

  const MyTextWidget({Key key, this.text}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Container(
        padding: const EdgeInsets.all(4.0),
        color: Colors.blueGrey,
        child: Text(text),
      ),
    );
  }
}

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Container(color: Colors.blueGrey),
    );
  }
}
import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Row and Column',
      home: Scaffold(
        body: ListView(
          children: [
            IntrinsicHeight(
              child: Row(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: [
                  Expanded(child: MyWidget()),
                  Expanded(
                    flex: 3,
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.stretch,
                      children: [
                        MyTextWidget(
                          text:
                              'I like to believe that science is becoming mainstream.',
                        ),
                        MyTextWidget(
                          text:
                              'There is no known objects accounting for most of the effective gravity in the universe.',
                        ),
                        MyTextWidget(
                          text: "Let's explore because it's fun.",
                        ),
                      ],
                    ),
                  ),
                  Expanded(
                    child: Center(
                      child: SizedBox(height: 40.0, child: MyWidget()),
                    ),
                  ),
                ],
              ),
            ),
            Spacer(),
          ],
        ),
      ),
    ),
  );
}

class MyTextWidget extends StatelessWidget {
  final String text;

  const MyTextWidget({Key key, this.text}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Container(
        padding: const EdgeInsets.all(4.0),
        color: Colors.blueGrey,
        child: Text(text),
      ),
    );
  }
}

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Container(color: Colors.blueGrey),
    );
  }
}

Upvotes: 28

Mol0ko
Mol0ko

Reputation: 3288

@Thierry's answer is good. But if your row has dynamic height (for example your subtitles have undefined length and row should expand height that depends on it) then you can use Stack widget as root widget of your list item to handle this. Here is working code:

  @override
  Widget build(BuildContext context) {
    final leadingWidgetWidth = 120.0;

    return Stack(children: [
      Positioned.fill(
        child: Container(
          alignment: Alignment.centerLeft,
          // This child will fill full height, replace it with your leading widget
          child: Container(
            color: Colors.blue,
            width: leadingWidgetWidth,
          ),
        ),
      ),
      Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          SizedBox(width: leadingWidgetWidth),
          Expanded(
            // Here your column with texts
            child: Column(
              mainAxisAlignment: MainAxisAlignment.start,
              children: [
                Text('Title'),
                Text('Some dynamic text'),
                Text('Some dynamic text'),
              ],
            ),
          ),
          Expanded(
            // Here your trailing widget
            child: Container(color: Colors.blueGrey),
          )
        ],
      )
    ]);
  }

Upvotes: 17

AngDrew
AngDrew

Reputation: 206

if you want them to have a maximum size of the main-axis you can add an attribute mainAxisSize: MainAxisSize.max if you want it to be minimum size, then use MainAxisSize.min instead (works on Row and Column)

if you want to make a cross-axis on max size, then you can add SizedBox before them and then add height or width with double.infinity like this height: double.infinity

Upvotes: 2

Related Questions