Better ListTile leading/trailing widget alignment (#26778)
This commit is contained in:
parent
db7e4fbbc4
commit
c8379ad54f
@ -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));
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user