Unverified Commit 26a5f5c3 authored by Ayush Bherwani's avatar Ayush Bherwani Committed by GitHub

[ListTileTheme] adds properties to customize tile color at theme level (#61532)

parent d7933fad
...@@ -52,6 +52,8 @@ class ListTileTheme extends InheritedTheme { ...@@ -52,6 +52,8 @@ class ListTileTheme extends InheritedTheme {
this.iconColor, this.iconColor,
this.textColor, this.textColor,
this.contentPadding, this.contentPadding,
this.tileColor,
this.selectedTileColor,
Widget child, Widget child,
}) : super(key: key, child: child); }) : super(key: key, child: child);
...@@ -68,6 +70,8 @@ class ListTileTheme extends InheritedTheme { ...@@ -68,6 +70,8 @@ class ListTileTheme extends InheritedTheme {
Color iconColor, Color iconColor,
Color textColor, Color textColor,
EdgeInsetsGeometry contentPadding, EdgeInsetsGeometry contentPadding,
Color tileColor,
Color selectedTileColor,
@required Widget child, @required Widget child,
}) { }) {
assert(child != null); assert(child != null);
...@@ -83,6 +87,8 @@ class ListTileTheme extends InheritedTheme { ...@@ -83,6 +87,8 @@ class ListTileTheme extends InheritedTheme {
iconColor: iconColor ?? parent.iconColor, iconColor: iconColor ?? parent.iconColor,
textColor: textColor ?? parent.textColor, textColor: textColor ?? parent.textColor,
contentPadding: contentPadding ?? parent.contentPadding, contentPadding: contentPadding ?? parent.contentPadding,
tileColor: tileColor ?? parent.tileColor,
selectedTileColor: selectedTileColor ?? parent.selectedTileColor,
child: child, child: child,
); );
}, },
...@@ -113,6 +119,18 @@ class ListTileTheme extends InheritedTheme { ...@@ -113,6 +119,18 @@ class ListTileTheme extends InheritedTheme {
/// and [trailing] widgets. /// and [trailing] widgets.
final EdgeInsetsGeometry contentPadding; final EdgeInsetsGeometry contentPadding;
/// If specified, defines the background color for `ListTile` when
/// [ListTile.selected] is false.
///
/// If [ListTile.tileColor] is provided, [tileColor] is ignored.
final Color tileColor;
/// If specified, defines the background color for `ListTile` when
/// [ListTile.selected] is true.
///
/// If [ListTile.selectedTileColor] is provided, [selectedTileColor] is ignored.
final Color selectedTileColor;
/// The closest instance of this class that encloses the given context. /// The closest instance of this class that encloses the given context.
/// ///
/// Typical usage is as follows: /// Typical usage is as follows:
...@@ -136,6 +154,8 @@ class ListTileTheme extends InheritedTheme { ...@@ -136,6 +154,8 @@ class ListTileTheme extends InheritedTheme {
iconColor: iconColor, iconColor: iconColor,
textColor: textColor, textColor: textColor,
contentPadding: contentPadding, contentPadding: contentPadding,
tileColor: tileColor,
selectedTileColor: selectedTileColor,
child: child, child: child,
); );
} }
...@@ -148,7 +168,9 @@ class ListTileTheme extends InheritedTheme { ...@@ -148,7 +168,9 @@ class ListTileTheme extends InheritedTheme {
|| selectedColor != oldWidget.selectedColor || selectedColor != oldWidget.selectedColor
|| iconColor != oldWidget.iconColor || iconColor != oldWidget.iconColor
|| textColor != oldWidget.textColor || textColor != oldWidget.textColor
|| contentPadding != oldWidget.contentPadding; || contentPadding != oldWidget.contentPadding
|| tileColor != oldWidget.tileColor
|| selectedTileColor != oldWidget.selectedTileColor;
} }
} }
...@@ -839,14 +861,16 @@ class ListTile extends StatelessWidget { ...@@ -839,14 +861,16 @@ class ListTile extends StatelessWidget {
/// {@macro flutter.widgets.Focus.autofocus} /// {@macro flutter.widgets.Focus.autofocus}
final bool autofocus; final bool autofocus;
/// Defines the background color of `ListTile when [selected] is false. /// Defines the background color of `ListTile` when [selected] is false.
/// ///
/// By default, the value of `tileColor` is [Colors.transparent]. /// When the value is null, the `tileColor` is set to [ListTileTheme.tileColor]
/// if it's not null and to [Colors.transparent] if it's null.
final Color tileColor; final Color tileColor;
/// Defines the background color of `ListTile` when [selected] is true. /// Defines the background color of `ListTile` when [selected] is true.
/// ///
/// By default, the value of `selectedListColor` is [Colors.transparent]. /// When the value if null, the `selectedTileColor` is set to [ListTileTheme.selectedTileColor]
/// if it's not null and to [Colors.transparent] if it's null.
final Color selectedTileColor; final Color selectedTileColor;
/// Add a one pixel border in between each tile. If color isn't specified the /// Add a one pixel border in between each tile. If color isn't specified the
...@@ -954,12 +978,20 @@ class ListTile extends StatelessWidget { ...@@ -954,12 +978,20 @@ class ListTile extends StatelessWidget {
: style.copyWith(color: color); : style.copyWith(color: color);
} }
Color _tileBackgroundColor() { Color _tileBackgroundColor(ListTileTheme tileTheme) {
if (!selected && tileColor != null) if (!selected) {
return tileColor; if (tileColor != null)
return tileColor;
if (tileTheme?.tileColor != null)
return tileTheme.tileColor;
}
if (selected && selectedTileColor != null) if (selected) {
return selectedTileColor; if (selectedTileColor != null)
return selectedTileColor;
if (tileTheme?.selectedTileColor != null)
return tileTheme.selectedTileColor;
}
return Colors.transparent; return Colors.transparent;
} }
...@@ -1036,7 +1068,7 @@ class ListTile extends StatelessWidget { ...@@ -1036,7 +1068,7 @@ class ListTile extends StatelessWidget {
selected: selected, selected: selected,
enabled: enabled, enabled: enabled,
child: ColoredBox( child: ColoredBox(
color: _tileBackgroundColor(), color: _tileBackgroundColor(tileTheme),
child: SafeArea( child: SafeArea(
top: false, top: false,
bottom: false, bottom: false,
......
...@@ -1610,4 +1610,86 @@ void main() { ...@@ -1610,4 +1610,86 @@ void main() {
expect(isSelected, isTrue); expect(isSelected, isTrue);
expect(coloredBox.color, defaultColor); expect(coloredBox.color, defaultColor);
}); });
testWidgets('ListTile respects ListTileTheme\'s tileColor & selectedTileColor', (WidgetTester tester) async {
ListTileTheme theme;
bool isSelected = false;
await tester.pumpWidget(
MaterialApp(
home: Material(
child: ListTileTheme(
selectedTileColor: Colors.green,
tileColor: Colors.red,
child: Center(
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
theme = ListTileTheme.of(context);
return ListTile(
selected: isSelected,
onTap: () {
setState(()=> isSelected = !isSelected);
},
title: const Text('Title'),
);
},
),
),
),
),
),
);
ColoredBox coloredBox = tester.widget(find.byType(ColoredBox));
expect(coloredBox.color, theme.tileColor);
// Tap on tile to change isSelected.
await tester.tap(find.byType(ListTile));
await tester.pumpAndSettle();
coloredBox = tester.widget(find.byType(ColoredBox));
expect(coloredBox.color, theme.selectedTileColor);
});
testWidgets('ListTileTheme\'s tileColor & selectedTileColor are overridden by ListTile properties', (WidgetTester tester) async {
bool isSelected = false;
const Color tileColor = Colors.brown;
const Color selectedTileColor = Colors.purple;
await tester.pumpWidget(
MaterialApp(
home: Material(
child: ListTileTheme(
selectedTileColor: Colors.green,
tileColor: Colors.red,
child: Center(
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return ListTile(
tileColor: tileColor,
selectedTileColor: selectedTileColor,
selected: isSelected,
onTap: () {
setState(()=> isSelected = !isSelected);
},
title: const Text('Title'),
);
},
),
),
),
),
),
);
ColoredBox coloredBox = tester.widget(find.byType(ColoredBox));
expect(coloredBox.color, tileColor);
// Tap on tile to change isSelected.
await tester.tap(find.byType(ListTile));
await tester.pumpAndSettle();
coloredBox = tester.widget(find.byType(ColoredBox));
expect(coloredBox.color, selectedTileColor);
});
} }
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