Unverified Commit e9a47599 authored by jBrennen's avatar jBrennen Committed by GitHub

#57730 - Support custom shapes for ListTiles (#57733)

parent 395d27aa
...@@ -44,6 +44,7 @@ class ListTileTheme extends InheritedTheme { ...@@ -44,6 +44,7 @@ class ListTileTheme extends InheritedTheme {
const ListTileTheme({ const ListTileTheme({
Key key, Key key,
this.dense = false, this.dense = false,
this.shape,
this.style = ListTileStyle.list, this.style = ListTileStyle.list,
this.selectedColor, this.selectedColor,
this.iconColor, this.iconColor,
...@@ -59,6 +60,7 @@ class ListTileTheme extends InheritedTheme { ...@@ -59,6 +60,7 @@ class ListTileTheme extends InheritedTheme {
static Widget merge({ static Widget merge({
Key key, Key key,
bool dense, bool dense,
ShapeBorder shape,
ListTileStyle style, ListTileStyle style,
Color selectedColor, Color selectedColor,
Color iconColor, Color iconColor,
...@@ -73,6 +75,7 @@ class ListTileTheme extends InheritedTheme { ...@@ -73,6 +75,7 @@ class ListTileTheme extends InheritedTheme {
return ListTileTheme( return ListTileTheme(
key: key, key: key,
dense: dense ?? parent.dense, dense: dense ?? parent.dense,
shape: shape ?? parent.shape,
style: style ?? parent.style, style: style ?? parent.style,
selectedColor: selectedColor ?? parent.selectedColor, selectedColor: selectedColor ?? parent.selectedColor,
iconColor: iconColor ?? parent.iconColor, iconColor: iconColor ?? parent.iconColor,
...@@ -87,6 +90,9 @@ class ListTileTheme extends InheritedTheme { ...@@ -87,6 +90,9 @@ class ListTileTheme extends InheritedTheme {
/// If true then [ListTile]s will have the vertically dense layout. /// If true then [ListTile]s will have the vertically dense layout.
final bool dense; final bool dense;
/// If specified, [shape] defines the shape of the [ListTile]'s [InkWell] border.
final ShapeBorder shape;
/// If specified, [style] defines the font used for [ListTile] titles. /// If specified, [style] defines the font used for [ListTile] titles.
final ListTileStyle style; final ListTileStyle style;
...@@ -122,6 +128,7 @@ class ListTileTheme extends InheritedTheme { ...@@ -122,6 +128,7 @@ class ListTileTheme extends InheritedTheme {
final ListTileTheme ancestorTheme = context.findAncestorWidgetOfExactType<ListTileTheme>(); final ListTileTheme ancestorTheme = context.findAncestorWidgetOfExactType<ListTileTheme>();
return identical(this, ancestorTheme) ? child : ListTileTheme( return identical(this, ancestorTheme) ? child : ListTileTheme(
dense: dense, dense: dense,
shape: shape,
style: style, style: style,
selectedColor: selectedColor, selectedColor: selectedColor,
iconColor: iconColor, iconColor: iconColor,
...@@ -134,6 +141,7 @@ class ListTileTheme extends InheritedTheme { ...@@ -134,6 +141,7 @@ class ListTileTheme extends InheritedTheme {
@override @override
bool updateShouldNotify(ListTileTheme oldWidget) { bool updateShouldNotify(ListTileTheme oldWidget) {
return dense != oldWidget.dense return dense != oldWidget.dense
|| shape != oldWidget.shape
|| style != oldWidget.style || style != oldWidget.style
|| selectedColor != oldWidget.selectedColor || selectedColor != oldWidget.selectedColor
|| iconColor != oldWidget.iconColor || iconColor != oldWidget.iconColor
...@@ -637,6 +645,7 @@ class ListTile extends StatelessWidget { ...@@ -637,6 +645,7 @@ class ListTile extends StatelessWidget {
this.isThreeLine = false, this.isThreeLine = false,
this.dense, this.dense,
this.visualDensity, this.visualDensity,
this.shape,
this.contentPadding, this.contentPadding,
this.enabled = true, this.enabled = true,
this.onTap, this.onTap,
...@@ -713,6 +722,15 @@ class ListTile extends StatelessWidget { ...@@ -713,6 +722,15 @@ class ListTile extends StatelessWidget {
/// within a [Theme]. /// within a [Theme].
final VisualDensity visualDensity; final VisualDensity visualDensity;
/// The shape of the tile's [InkWell].
///
/// Defines the tile's [InkWell.customBorder].
///
/// If this property is null then [ThemeData.cardTheme.shape] is used.
/// If that's null then the shape will be a [RoundedRectangleBorder] with a
/// circular corner radius of 4.0.
final ShapeBorder shape;
/// The tile's internal padding. /// The tile's internal padding.
/// ///
/// Insets a [ListTile]'s contents: its [leading], [title], [subtitle], /// Insets a [ListTile]'s contents: its [leading], [title], [subtitle],
...@@ -932,6 +950,7 @@ class ListTile extends StatelessWidget { ...@@ -932,6 +950,7 @@ class ListTile extends StatelessWidget {
); );
return InkWell( return InkWell(
customBorder: shape ?? tileTheme.shape,
onTap: enabled ? onTap : null, onTap: enabled ? onTap : null,
onLongPress: enabled ? onLongPress : null, onLongPress: enabled ? onLongPress : null,
mouseCursor: effectiveMouseCursor, mouseCursor: effectiveMouseCursor,
......
...@@ -263,6 +263,7 @@ void main() { ...@@ -263,6 +263,7 @@ void main() {
bool enabled = true, bool enabled = true,
bool dense = false, bool dense = false,
bool selected = false, bool selected = false,
ShapeBorder shape,
Color selectedColor, Color selectedColor,
Color iconColor, Color iconColor,
Color textColor, Color textColor,
...@@ -272,6 +273,7 @@ void main() { ...@@ -272,6 +273,7 @@ void main() {
child: Center( child: Center(
child: ListTileTheme( child: ListTileTheme(
dense: dense, dense: dense,
shape: shape,
selectedColor: selectedColor, selectedColor: selectedColor,
iconColor: iconColor, iconColor: iconColor,
textColor: textColor, textColor: textColor,
...@@ -296,9 +298,13 @@ void main() { ...@@ -296,9 +298,13 @@ void main() {
const Color green = Color(0xFF00FF00); const Color green = Color(0xFF00FF00);
const Color red = Color(0xFFFF0000); const Color red = Color(0xFFFF0000);
const ShapeBorder roundedShape = RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4.0)),
);
Color iconColor(Key key) => tester.state<TestIconState>(find.byKey(key)).iconTheme.color; Color iconColor(Key key) => tester.state<TestIconState>(find.byKey(key)).iconTheme.color;
Color textColor(Key key) => tester.state<TestTextState>(find.byKey(key)).textStyle.color; Color textColor(Key key) => tester.state<TestTextState>(find.byKey(key)).textStyle.color;
ShapeBorder inkWellBorder() => tester.widget<InkWell>(find.descendant(of: find.byType(ListTile), matching: find.byType(InkWell))).customBorder;
// A selected ListTile's leading, trailing, and text get the primary color by default // A selected ListTile's leading, trailing, and text get the primary color by default
await tester.pumpWidget(buildFrame(selected: true)); await tester.pumpWidget(buildFrame(selected: true));
...@@ -341,6 +347,10 @@ void main() { ...@@ -341,6 +347,10 @@ void main() {
expect(iconColor(trailingKey), theme.disabledColor); expect(iconColor(trailingKey), theme.disabledColor);
expect(textColor(titleKey), theme.disabledColor); expect(textColor(titleKey), theme.disabledColor);
expect(textColor(subtitleKey), theme.disabledColor); expect(textColor(subtitleKey), theme.disabledColor);
// A selected ListTile's InkWell gets the ListTileTheme's shape
await tester.pumpWidget(buildFrame(selected: true, shape: roundedShape));
expect(inkWellBorder(), roundedShape);
}); });
testWidgets('ListTile semantics', (WidgetTester tester) async { testWidgets('ListTile semantics', (WidgetTester tester) async {
......
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