Unverified Commit c8379ad5 authored by Mehmet Fidanboylu's avatar Mehmet Fidanboylu Committed by GitHub

Better ListTile leading/trailing widget alignment (#26778)

parent db7e4fbb
......@@ -988,26 +988,20 @@ class _RenderListTile extends RenderBox {
// This attempts to implement the redlines for the vertical position of the
// leading and trailing icons on the spec page:
// https://material.io/design/components/lists.html#specs
// Some liberties have been taken to handle cases that aren't covered by
// that specification, such as leading and trailing widgets with weird
// sizes, "one-line" list tiles with title widgets that span multiple lines,
// etc.
// The interpretation for these red lines is as follows:
// - For large tiles (> 72dp), both leading and trailing controls should be
// a fixed distance from top. As per guidelines this is set to 16dp.
// - For smaller tiles, trailing should always be centered. Leading can be
// centered or closer to the top. It should never be further than 16dp
// to the top.
double leadingY;
double trailingY;
if (isOneLine) {
leadingY = (defaultTileHeight - leadingSize.height) / 2.0;
trailingY = (defaultTileHeight - trailingSize.height) / 2.0;
} else if (isTwoLine) {
if (isDense) {
leadingY = 12.0; // by extrapolation
trailingY = 20.0; // by extrapolation
} else {
leadingY = leadingSize.height <= 40.0 ? 16.0 : 8.0;
trailingY = 24.0;
}
} else {
if (tileHeight > 72.0) {
leadingY = 16.0;
trailingY = 16.0;
} else {
leadingY = math.min((tileHeight - leadingSize.height) / 2.0, 16.0);
trailingY = (tileHeight - trailingSize.height) / 2.0;
}
switch (textDirection) {
......
......@@ -585,11 +585,11 @@ void main() {
),
),
);
// LEFT TOP WIDTH HEIGHT
// LEFT TOP WIDTH HEIGHT
expect(tester.getRect(find.byType(ListTile).at(0)), Rect.fromLTWH( 0.0, 0.0, 800.0, 177.0));
expect(tester.getRect(find.byType(CircleAvatar).at(0)), Rect.fromLTWH( 16.0, 4.0, 40.0, 40.0));
expect(tester.getRect(find.byType(Placeholder).at(0)), Rect.fromLTWH(800.0 - 24.0 - 16.0, 12.0, 24.0, 24.0));
expect(tester.getRect(find.byType(ListTile).at(1)), Rect.fromLTWH( 0.0, 177.0, 800.0, 48.0));
expect(tester.getRect(find.byType(CircleAvatar).at(0)), Rect.fromLTWH( 16.0, 16.0, 40.0, 40.0));
expect(tester.getRect(find.byType(Placeholder).at(0)), Rect.fromLTWH(800.0 - 24.0 - 16.0, 16.0, 24.0, 24.0));
expect(tester.getRect(find.byType(ListTile).at(1)), Rect.fromLTWH( 0.0, 177.0, 800.0, 48.0));
expect(tester.getRect(find.byType(CircleAvatar).at(1)), Rect.fromLTWH( 16.0, 177.0 + 4.0, 40.0, 40.0));
expect(tester.getRect(find.byType(Placeholder).at(1)), Rect.fromLTWH(800.0 - 24.0 - 16.0, 177.0 + 12.0, 24.0, 24.0));
......@@ -615,11 +615,11 @@ void main() {
),
);
await tester.pump(const Duration(seconds: 2)); // the text styles are animated when we change dense
// LEFT TOP WIDTH HEIGHT
// LEFT TOP WIDTH HEIGHT
expect(tester.getRect(find.byType(ListTile).at(0)), Rect.fromLTWH( 0.0, 0.0, 800.0, 216.0));
expect(tester.getRect(find.byType(CircleAvatar).at(0)), Rect.fromLTWH( 16.0, 8.0, 40.0, 40.0));
expect(tester.getRect(find.byType(CircleAvatar).at(0)), Rect.fromLTWH( 16.0, 16.0, 40.0, 40.0));
expect(tester.getRect(find.byType(Placeholder).at(0)), Rect.fromLTWH(800.0 - 24.0 - 16.0, 16.0, 24.0, 24.0));
expect(tester.getRect(find.byType(ListTile).at(1)), Rect.fromLTWH( 0.0, 216.0, 800.0, 56.0));
expect(tester.getRect(find.byType(ListTile).at(1)), Rect.fromLTWH( 0.0, 216.0 , 800.0, 56.0));
expect(tester.getRect(find.byType(CircleAvatar).at(1)), Rect.fromLTWH( 16.0, 216.0 + 8.0, 40.0, 40.0));
expect(tester.getRect(find.byType(Placeholder).at(1)), Rect.fromLTWH(800.0 - 24.0 - 16.0, 216.0 + 16.0, 24.0, 24.0));
......@@ -650,8 +650,8 @@ void main() {
);
// LEFT TOP WIDTH HEIGHT
expect(tester.getRect(find.byType(ListTile).at(0)), Rect.fromLTWH( 0.0, 0.0, 800.0, 180.0));
expect(tester.getRect(find.byType(CircleAvatar).at(0)), Rect.fromLTWH( 16.0, 12.0, 40.0, 40.0));
expect(tester.getRect(find.byType(Placeholder).at(0)), Rect.fromLTWH(800.0 - 24.0 - 16.0, 20.0, 24.0, 24.0));
expect(tester.getRect(find.byType(CircleAvatar).at(0)), Rect.fromLTWH( 16.0, 16.0, 40.0, 40.0));
expect(tester.getRect(find.byType(Placeholder).at(0)), Rect.fromLTWH(800.0 - 24.0 - 16.0, 16.0, 24.0, 24.0));
expect(tester.getRect(find.byType(ListTile).at(1)), Rect.fromLTWH( 0.0, 180.0, 800.0, 64.0));
expect(tester.getRect(find.byType(CircleAvatar).at(1)), Rect.fromLTWH( 16.0, 180.0 + 12.0, 40.0, 40.0));
expect(tester.getRect(find.byType(Placeholder).at(1)), Rect.fromLTWH(800.0 - 24.0 - 16.0, 180.0 + 20.0, 24.0, 24.0));
......@@ -682,7 +682,7 @@ void main() {
// LEFT TOP WIDTH HEIGHT
expect(tester.getRect(find.byType(ListTile).at(0)), Rect.fromLTWH( 0.0, 0.0, 800.0, 180.0));
expect(tester.getRect(find.byType(CircleAvatar).at(0)), Rect.fromLTWH( 16.0, 16.0, 40.0, 40.0));
expect(tester.getRect(find.byType(Placeholder).at(0)), Rect.fromLTWH(800.0 - 24.0 - 16.0, 24.0, 24.0, 24.0));
expect(tester.getRect(find.byType(Placeholder).at(0)), Rect.fromLTWH(800.0 - 24.0 - 16.0, 16.0, 24.0, 24.0));
expect(tester.getRect(find.byType(ListTile).at(1)), Rect.fromLTWH( 0.0, 180.0, 800.0, 72.0));
expect(tester.getRect(find.byType(CircleAvatar).at(1)), Rect.fromLTWH( 16.0, 180.0 + 16.0, 40.0, 40.0));
expect(tester.getRect(find.byType(Placeholder).at(1)), Rect.fromLTWH(800.0 - 24.0 - 16.0, 180.0 + 24.0, 24.0, 24.0));
......@@ -754,5 +754,35 @@ void main() {
expect(tester.getRect(find.byType(ListTile).at(1)), Rect.fromLTWH( 0.0, 180.0, 800.0, 88.0));
expect(tester.getRect(find.byType(CircleAvatar).at(1)), Rect.fromLTWH( 16.0, 180.0 + 16.0, 40.0, 40.0));
expect(tester.getRect(find.byType(Placeholder).at(1)), Rect.fromLTWH(800.0 - 24.0 - 16.0, 180.0 + 16.0, 24.0, 24.0));
// "ONE-LINE" with Small Leading Widget
await tester.pumpWidget(
MaterialApp(
home: Material(
child: ListView(
children: const <Widget>[
ListTile(
leading: SizedBox(height:12.0, width:24.0, child: Placeholder()),
trailing: SizedBox(height: 24.0, width: 24.0, child: Placeholder()),
title: Text('A\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM'),
),
ListTile(
leading: SizedBox(height:12.0, width:24.0, child: Placeholder()),
trailing: SizedBox(height: 24.0, width: 24.0, child: Placeholder()),
title: Text('A'),
),
],
),
),
),
);
await tester.pump(const Duration(seconds: 2)); // the text styles are animated when we change dense
// LEFT TOP WIDTH HEIGHT
expect(tester.getRect(find.byType(ListTile).at(0)), Rect.fromLTWH( 0.0, 0.0, 800.0, 216.0));
expect(tester.getRect(find.byType(Placeholder).at(0)), Rect.fromLTWH( 16.0, 16.0, 24.0, 12.0));
expect(tester.getRect(find.byType(Placeholder).at(1)), Rect.fromLTWH(800.0 - 24.0 - 16.0, 16.0, 24.0, 24.0));
expect(tester.getRect(find.byType(ListTile).at(1)), Rect.fromLTWH( 0.0, 216.0 , 800.0, 56.0));
expect(tester.getRect(find.byType(Placeholder).at(2)), Rect.fromLTWH( 16.0, 216.0 + 16.0, 24.0, 12.0));
expect(tester.getRect(find.byType(Placeholder).at(3)), Rect.fromLTWH(800.0 - 24.0 - 16.0, 216.0 + 16.0, 24.0, 24.0));
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment