Search code examples
flutterflutter-layoutflutter-text

Is there a way to automatically size the row heights of a Table widget based on available space in Flutter?


I have been trying to create a table in Flutter with the Table widget and have it expand until the bottom of the screen, without having to scroll to view the entire table. However, it seems like the Text widgets force the rows to have a specific height, causing the last rows to overflow.

An interesting side note is that the Expanded widget where the Table lives does not overflow the screen, therefore no error message is shown even though the Table overflows the Expanded widget. Instead, it seems like the Table is overflowing within the Expanded widget.

Example code:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter table example',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter table example'),
        ),
        body: Column(
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.all(4.0),
              child: Image.network('https://imgs.xkcd.com/comics/minifigs.png'),
            ),
            Expanded(
              child: Container(
                padding: const EdgeInsets.all(6.0),
                child: Table(
                  columnWidths: {
                    0: FlexColumnWidth(1),
                    1: FlexColumnWidth(2),
                    2: FlexColumnWidth(2),
                  },
                  border: TableBorder(
                      horizontalInside: new BorderSide(color: Colors.grey[300], width: 1)
                  ),
                  defaultVerticalAlignment: TableCellVerticalAlignment.middle,
                  children:
                  List<TableRow>.generate(10, (int i){
                    return TableRow(
                        children: [
                          Padding(
                            padding: const EdgeInsets.all(8.0),
                            child: Text(
                              (1990 + i).toString(),
                              style: TextStyle(
                                fontWeight: FontWeight.bold,
                                fontSize: 14,
                              ),
                            ),
                          ),
                          Padding(
                            padding: const EdgeInsets.all(8.0),
                            child: Text(
                              'Normal people',
                              textAlign: TextAlign.center,
                            ),
                          ),
                          Padding(
                            padding: const EdgeInsets.all(8.0),
                            child: Text(
                              'Lego people',
                              textAlign: TextAlign.center,
                            ),
                          ),
                        ]
                    );
                  }),
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

And the output:

Screenshot of example app with overflowing table


Solution

  • Hope this helps

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter table example',
          home: Scaffold(
            appBar: AppBar(
              title: Text('Flutter table example'),
            ),
            body: Container(
              child: ListView(
                shrinkWrap:true,
                children: <Widget>[
                  Padding(
                    padding: const EdgeInsets.all(4.0),
                    child:
                        Image.network('https://imgs.xkcd.com/comics/minifigs.png'),
                  ),
                     Container(
                      padding: const EdgeInsets.all(6.0),
                      child: Table(
                        columnWidths: {
                          0: FlexColumnWidth(1),
                          1: FlexColumnWidth(2),
                          2: FlexColumnWidth(2),
                        },
                        border: TableBorder(
                            horizontalInside:
                                new BorderSide(color: Colors.grey[300], width: 1)),
                        defaultVerticalAlignment: TableCellVerticalAlignment.middle,
                        children: List<TableRow>.generate(20, (int i) {
                          return TableRow(children: [
                            Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: Text(
                                (1990 + i).toString(),
                                style: TextStyle(
                                  fontWeight: FontWeight.bold,
                                  fontSize: 14,
                                ),
                              ),
                            ),
                            Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: Text(
                                'Normal people',
                                textAlign: TextAlign.center,
                              ),
                            ),
                            Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: Text(
                                'Lego people',
                                textAlign: TextAlign.center,
                              ),
                            ),
                          ]);
                        }),
                      ),
                  ),
                ],
              ),
            ),
          ),
        );
      }
    }