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 { ...@@ -988,26 +988,20 @@ class _RenderListTile extends RenderBox {
// This attempts to implement the redlines for the vertical position of the // This attempts to implement the redlines for the vertical position of the
// leading and trailing icons on the spec page: // leading and trailing icons on the spec page:
// https://material.io/design/components/lists.html#specs // https://material.io/design/components/lists.html#specs
// Some liberties have been taken to handle cases that aren't covered by // The interpretation for these red lines is as follows:
// that specification, such as leading and trailing widgets with weird // - For large tiles (> 72dp), both leading and trailing controls should be
// sizes, "one-line" list tiles with title widgets that span multiple lines, // a fixed distance from top. As per guidelines this is set to 16dp.
// etc. // - 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 leadingY;
double trailingY; double trailingY;
if (isOneLine) { if (tileHeight > 72.0) {
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 {
leadingY = 16.0; leadingY = 16.0;
trailingY = 16.0; trailingY = 16.0;
} else {
leadingY = math.min((tileHeight - leadingSize.height) / 2.0, 16.0);
trailingY = (tileHeight - trailingSize.height) / 2.0;
} }
switch (textDirection) { switch (textDirection) {
......
...@@ -587,8 +587,8 @@ void main() { ...@@ -587,8 +587,8 @@ 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(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(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, 12.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, 177.0, 800.0, 48.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(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)); expect(tester.getRect(find.byType(Placeholder).at(1)), Rect.fromLTWH(800.0 - 24.0 - 16.0, 177.0 + 12.0, 24.0, 24.0));
...@@ -617,9 +617,9 @@ void main() { ...@@ -617,9 +617,9 @@ void main() {
await tester.pump(const Duration(seconds: 2)); // the text styles are animated when we change dense 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(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(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(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)); 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() { ...@@ -650,8 +650,8 @@ 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, 180.0)); 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(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, 20.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, 64.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(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)); 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() { ...@@ -682,7 +682,7 @@ 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, 180.0)); 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(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(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(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)); 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() { ...@@ -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(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(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)); 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