Search code examples
flutterflutter-layout

Make Container fill TableCell in Flutter


I'm trying to make a Table with two cells of the same width and height, so that the height depends on the size of the content. However, the smaller TableCell always shrinks:

This is what I have now

This is what I'm trying to implement:

This is what I'm trying to implement

Here's the code:

  Table(
    children: [
      TableRow(
        children: [
          TableCell(
            child: Container(
              color: Colors.green,
              child: Text(
                  'long text long text long text long text long text long text long text'),
            ),
          ),
          TableCell(
            child: Container(
              color: Colors.orange,
              child: Text('short text'),
            ),
          ),
        ],
      )
    ],
  ),

P.S. I could solve it by adding verticalAlignment: TableCellVerticalAlignment.fill, to the smaller cell, but any cell can be the smaller one, depending on the content. When I add this line to both cells, the whole table disappears. The only bypass I could imagine is to calculate the length of the content and find the smaller cell, but I wonder if there is a way to implement this UI directly with Flutter.

Would appreciate any help.


Solution

  • 1. Row with IntrinsicHeight

    IntrinsicHeight limits the height of the Row to the content size, which however is considered a 'relatively expensive' approach and is not recommended.

      IntrinsicHeight(
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Expanded(
                child: Container(
                    color: Colors.green,
                    child: Text(
                      'long text long text long text long text long text',
                    ))),
            Expanded(
                child: Container(
                    color: Colors.orange,
                    child: Text(
                      'short text',
                    ))),
          ],
        ),
      ),
    

    2. Table with TableCellVerticalAlignment.fill

    As mentioned in the question, the .fill option must not be used in the largest TableCell, because in this case the TableRow will have zero height. This is the preferred solution, because it doesn't have the 'expensiveness' issue of the previous one.

    final texts = ['long text long text long text long text long text', 'short text'];
    final colors = [Colors.green, Colors.orange];
    // find the longest text and its index
    final max = texts.asMap().entries.reduce(
          (a, b) => (a.value.length > b.value.length) ? a : b,
        );
    return Table(children: [
      TableRow(
        children: texts
            .asMap()
            .entries
            .map((e) => TableCell(
                // use .fill in all cells except the largest
                verticalAlignment: (e.key != max.key)
                    ? TableCellVerticalAlignment.fill
                    : TableCellVerticalAlignment.top,
                child: Container(
                  color: colors[e.key],
                  child: Text(e.value),
                )))
            .toList(),
      ),
    ]);