Search code examples
flutterflutter-columnflutter-expanded

How to make two Expanded widgets take the screen size based on their child in Flutter


I have the following code:

import 'package:flutter/material.dart';

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  final String longText = '''
Vestibulum dapibus sit amet ante et vehicula. Aliquam erat volutpat. 
Pellentesque ut velit odio. Nam varius interdum urna ac gravida. 
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. 
Curabitur dapibus in enim nec porta. Praesent tortor diam, tempus a massa eget, mattis imperdiet tellus. 
Aliquam porta pellentesque tellus sit amet dapibus. 
Vivamus dolor dui, dapibus sed risus ac, pellentesque convallis mauris. 
Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Vivamus egestas metus eget ipsum pretium scelerisque. 
Nulla tempus ligula venenatis faucibus suscipit. 
Aenean est tortor, elementum fermentum ullamcorper a, consectetur nec erat.

Quisque tincidunt finibus metus, eget vulputate turpis volutpat ac. 
Vivamus consectetur at ligula ac semper. Duis a justo sed tortor egestas sodales sed vitae sem. 
Mauris efficitur finibus lectus quis lacinia. 
Mauris velit odio, finibus et ipsum et, maximus iaculis diam. 
Phasellus ligula mi, gravida in enim et, fermentum tempus quam. 
Integer fermentum orci risus, eget aliquam nulla posuere eu. 
Donec dictum tristique nunc, in ullamcorper mi pulvinar ac. 
Integer sit amet laoreet nisi. Donec aliquet nibh nec rutrum aliquet. 
Mauris rutrum non ipsum et volutpat.
''';

  final String shortText =
      'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris venenatis hendrerit lectus sit amet venenatis.';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home Page'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            Expanded(
              child: Text(
                longText,
              ),
            ),
            Expanded(
              child: Container(
                color: Colors.teal,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

The output is as following:

enter image description here

This is good (half the space for Text, and the other half for the Container) and what I want, but for longer text. If I have a shorter text as the following:

child: Text(
  shortText,
),

Then the output will look like this:

enter image description here

There is an empty space between the Text and the Container and I know that it is because of the Expanded. But I want the Container to fill the remaining space until the last line of the Text. But again, if the Text is larger, then both the Text and the Container should take half of the screen as in the first photo.

If I replace the parent Expanded of the Text with Flexible, then it will look like this:

enter image description here

This is near to what I want, but again, there is an empty space below the Container.


Solution

  • Just let the Container fill all the remaining space and limit max height of the Text.

    You can control the size of children depends on parent size with LayoutBuilder.

    class HomePage extends StatelessWidget {
      const HomePage({super.key});
    
      // definition of long and short texts
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('Home Page'),
          ),
          body: Padding(
            padding: const EdgeInsets.all(16.0),
            child: LayoutBuilder(
              builder: (context, constraints) => Column(
                children: [
                  Container(
                    constraints: BoxConstraints(maxHeight: constraints.maxHeight / 2),
                    child: Text(longText),
                  ),
                  Expanded(child: Container(color: Colors.teal)),
                ],
              ),
            ),
          ),
        );
      }
    }
    

    I hope it helped.