feature(table-widget): Added intrinsicHeight to TableCellVerticalAlignment 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
This commit is contained in:
Gabriel Tavares
2023-11-28 20:13:09 -03:00
committed by GitHub
parent ef3c617061
commit 66935a82e8
3 changed files with 78 additions and 1 deletions

View File

@@ -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.
@@ -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:
@@ -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:
@@ -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);
}

View File

@@ -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);
});
}

View File

@@ -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
}