-
Notifications
You must be signed in to change notification settings - Fork 29.8k
Updated ListTile layout #17496
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Updated ListTile layout #17496
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I first read this, I was thinking that it specified the same padding for each of the items in the list tile separately, meaning that if you set it to 10.0, then there would be 20 pixels horizontally between the leading widget and the titles. It looks like this doesn't do that, but rather puts padding around the outside of the entire widget only, not the individual components (so setting it to 10.0 wouldn't affect internal horizontal padding). You might clear up the wording a bit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess that's the confusing difference between the ListTiles' padding and the ListTile's padding.
I've changed it to:
/// The tile's internal padding.
///
/// Insets a [ListTile]'s contents: its [leading], [title], [subtitle],
/// and [trailing] widgets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as above to clarify what it affects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be better to have the safe area outside of the padding? This way it might look a little close to a side notch if it's at the edge. And why only have it take effect horizontally?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you make these magic numbers into named constants?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto here, and below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't introduced one-time constants for the default tile heights and baselines because making up names for these values doesn't seems to make the code any more readable.
I did add a general comment about the dimensions and a pointer to the MD spec
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yay! We can add pointers to the MD spec again!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe convert this magic number into a named constant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of these (like this one) are only used once. It might be simpler to just have leading != null for that one conditional.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had it that way at one point but I found it easier to read/change the code by defining hasFoo vars for all of the children
abfb2ae to
ae94811
Compare
| final Decoration decoration = new BoxDecoration( | ||
| border: new Border( | ||
| bottom: Divider.createBorderSide(context, color: color), | ||
| border: new Border( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation is only one space: should be two.
| while (iterator.moveNext()) { | ||
| yield new DecoratedBox( | ||
| position: DecorationPosition.foreground, | ||
| position: DecorationPosition.foreground, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation
| position: DecorationPosition.foreground, | ||
| decoration: decoration, | ||
| child: tile, | ||
| child: tile, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for catching these indentOs. I must be developing indentation blindness :-)
|
|
||
| final double titleStart = hasLeading ? leadingSize.width <= 40.0 ? 56.0 : leadingSize.width + 16.0 : 0.0; | ||
| final BoxConstraints textConstraints = looseConstraints.tighten( | ||
| width: tileWidth - titleStart - (hasTrailing ? trailingSize.width + 16.0 : 0.0), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should that 16.0 also be _leadingTitleGap? (in which case it should probably be called _titleGap, or add a _trailingTitleGap).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. I used _kTitleGap
| case TextDirection.rtl: { | ||
| if (hasLeading) | ||
| _positionBox(leading, new Offset(tileWidth - leadingSize.width, leadingY)); | ||
| final double titleX = hasTrailing ? trailingSize.width + 16.0 : 0.0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this 16.0 should also be a named constant (e.g. _titleGap) to keep it consistent with the one above.
| static const double _kTitleGap = 16.0; // between the titles and the leading/trailing widgets | ||
|
|
||
| final Map<_ListTileSlot, RenderBox> slotToChild = <_ListTileSlot, RenderBox>{}; | ||
| final Map<RenderBox, _ListTileSlot> childToSlot = <RenderBox, _ListTileSlot>{}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a pattern we've seen several times now, we might want to factor it out into a common foundation class
| } | ||
|
|
||
| @override | ||
| bool get sizedByParent => false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't this the default?
|
|
||
| if (isOneLine) | ||
| return isDense ? 48.0 : 56.0; | ||
| else if (isTwoLine) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these elses can be omitted
| } | ||
| } | ||
|
|
||
| class _RenderListTileElement extends RenderObjectElement { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
generally speaking, we put the element with the widget, and the renderobject after (or before) them.
This reverts commit ee019c0.
| tileHeight = titleSize.height + subtitleSize.height; | ||
| titleY = 0.0; | ||
| subtitleY = titleSize.height; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are lines 780 to 795 based on?

Updated ListTile's layout to match the current Material spec: https://material.io/design/components/lists.html#specs
Unless textScaleFactor causes the layout to overflow, the title and subtitle baselines are now located per the spec. Similarly the height of the tile and the layout of the title/subtitle relative to the leading widget are as specified.
Added a
contentPaddingparameter to ListTileTheme and ListTile to enable overriding the default 16dps padding on the tile's left and right .