Skip to content

Commit

Permalink
feature(table-widget): Added intrinsicHeight to TableCellVerticalAlig…
Browse files Browse the repository at this point in the history
…nment enum. (#130264)

**What has been done?**
----------------------
Added new enumeration in `TableCellVerticalAlignment`, which sets the cell size to the same as the topmost cell. There are no noticeable problems in using it in all cells together, as there are in `TableCellVerticalAlignment.fill` which is made not to be used in all cells together because it has another purpose.

**Explanation of the logic**
----------------------
An assignment was made (which already existed in `TableCellVerticalAlignment.top; middle and bottom`) that assigns `rowHeight` the maximum double between the initialized height and the height of its child.

![image](https://github.com/flutter/flutter/assets/69699209/0fc9c168-5638-494b-aa0c-c579d0494c5e)

Basically, defining a minimum cell height based on its child, and letting each table row have its own height stipulated from the largest element, creating an `IntrinsicHeight` for TableCell automatically.

![image](https://github.com/flutter/flutter/assets/69699209/488b258a-3d25-4655-a9a0-381680468dec)

As the `TableCellVerticalAlignment` logic already provides for the use of the height of the largest cell in the row, it was possible to reuse this logic, and just not make the break statement that exists to fill in the calculation for `intrinsicHeight`.

Real example in an Android application after added enumeration
----------------------
![image](https://github.com/flutter/flutter/assets/69699209/51dce88d-f0f5-4644-942a-11ad218ffca0)

Opened issue
----------------------
FIX: #130261
  • Loading branch information
gbtb16 authored Nov 28, 2023
1 parent ef3c617 commit 66935a8
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 1 deletion.
8 changes: 7 additions & 1 deletion packages/flutter/lib/src/rendering/table.dart
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,10 @@ enum TableCellVerticalAlignment {

/// Cells with this alignment are sized to be as tall as the row, then made to fit the row.
/// If all the cells have this alignment, then the row will have zero height.
fill
fill,

/// Cells with this alignment are sized to be the same height as the tallest cell in the row.
intrinsicHeight
}

/// A table where the columns and rows are sized to fit the contents of the cells.
Expand Down Expand Up @@ -1048,6 +1051,7 @@ class RenderTable extends RenderBox {
case TableCellVerticalAlignment.top:
case TableCellVerticalAlignment.middle:
case TableCellVerticalAlignment.bottom:
case TableCellVerticalAlignment.intrinsicHeight:
final Size childSize = child.getDryLayout(BoxConstraints.tightFor(width: widths[x]));
rowHeight = math.max(rowHeight, childSize.height);
case TableCellVerticalAlignment.fill:
Expand Down Expand Up @@ -1126,6 +1130,7 @@ class RenderTable extends RenderBox {
case TableCellVerticalAlignment.top:
case TableCellVerticalAlignment.middle:
case TableCellVerticalAlignment.bottom:
case TableCellVerticalAlignment.intrinsicHeight:
child.layout(BoxConstraints.tightFor(width: widths[x]), parentUsesSize: true);
rowHeight = math.max(rowHeight, child.size.height);
case TableCellVerticalAlignment.fill:
Expand Down Expand Up @@ -1154,6 +1159,7 @@ class RenderTable extends RenderBox {
case TableCellVerticalAlignment.bottom:
childParentData.offset = Offset(positions[x], rowTop + rowHeight - child.size.height);
case TableCellVerticalAlignment.fill:
case TableCellVerticalAlignment.intrinsicHeight:
child.layout(BoxConstraints.tightFor(width: widths[x], height: rowHeight));
childParentData.offset = Offset(positions[x], rowTop);
}
Expand Down
29 changes: 29 additions & 0 deletions packages/flutter/test/rendering/table_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -309,4 +309,33 @@ void main() {
// Same result.
expect(columnWidth.flex(<RenderBox>[]), flexValue);
});

test('TableRows with differents constraints, but vertically with intrisicHeight', () {
const BoxConstraints firstConstraints = BoxConstraints.tightFor(width: 100, height: 100);
const BoxConstraints secondConstraints = BoxConstraints.tightFor(width: 200, height: 200);

final RenderTable table = RenderTable(
textDirection: TextDirection.rtl,
defaultVerticalAlignment: TableCellVerticalAlignment.intrinsicHeight,
children: <List<RenderBox>>[
<RenderBox>[
RenderConstrainedBox(additionalConstraints: firstConstraints),
RenderConstrainedBox(additionalConstraints: secondConstraints),
]
],
columnWidths: const <int, TableColumnWidth>{
0: FlexColumnWidth(),
1: FlexColumnWidth(),
},
);

const Size size = Size(300.0, 300.0);

// Layout the table with a fixed size.
layout(table, constraints: BoxConstraints.tight(size));

// Make sure the table has a size and that the children are filled vertically to the highest cell.
expect(table.size, equals(size));
expect(table.defaultVerticalAlignment, TableCellVerticalAlignment.intrinsicHeight);
});
}
42 changes: 42 additions & 0 deletions packages/flutter/test/widgets/table_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1080,5 +1080,47 @@ void main() {
);
});

testWidgets('Set defaultVerticalAlignment to intrisic height and check their heights', (WidgetTester tester) async {
final Widget table = Directionality(
textDirection: TextDirection.ltr,
child: Table(
defaultVerticalAlignment: TableCellVerticalAlignment.intrinsicHeight,
children: const <TableRow>[
TableRow(
children: <Widget>[
SizedBox(height: 100, child: Text('A')),
SizedBox(height: 200, child: Text('B')),
],
),
TableRow(
children: <Widget>[
SizedBox(height: 200, child: Text('C')),
SizedBox(height: 300, child: Text('D')),
],
),
],
),
);

// load and check if render object was created.
await tester.pumpWidget(table);
expect(find.byWidget(table), findsOneWidget);

final RenderBox boxA = tester.renderObject(find.text('A'));
final RenderBox boxB = tester.renderObject(find.text('B'));

// boxA and boxB must be the same height, even though boxB is higher than boxA initially.
expect(boxA.size.height, equals(boxB.size.height));

final RenderBox boxC = tester.renderObject(find.text('C'));
final RenderBox boxD = tester.renderObject(find.text('D'));

// boxC and boxD must be the same height, even though boxD is higher than boxC initially.
expect(boxC.size.height, equals(boxD.size.height));

// boxD (300.0h) should be higher than boxA (200.0h) which has the same height of boxB.
expect(boxD.size.height, greaterThan(boxA.size.height));
});

// TODO(ianh): Test handling of TableCell object
}

0 comments on commit 66935a8

Please sign in to comment.