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 {
this.iconColor,
this.textColor,
this.contentPadding,
this.tileColor,
this.selectedTileColor,
Widget child,
}) : super(key: key, child: child);
......@@ -68,6 +70,8 @@ class ListTileTheme extends InheritedTheme {
Color iconColor,
Color textColor,
EdgeInsetsGeometry contentPadding,
Color tileColor,
Color selectedTileColor,
@required Widget child,
}) {
assert(child != null);
......@@ -83,6 +87,8 @@ class ListTileTheme extends InheritedTheme {
iconColor: iconColor ?? parent.iconColor,
textColor: textColor ?? parent.textColor,
contentPadding: contentPadding ?? parent.contentPadding,
tileColor: tileColor ?? parent.tileColor,
selectedTileColor: selectedTileColor ?? parent.selectedTileColor,
child: child,
);
},
......@@ -113,6 +119,18 @@ class ListTileTheme extends InheritedTheme {
/// and [trailing] widgets.
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.
///
/// Typical usage is as follows:
......@@ -136,6 +154,8 @@ class ListTileTheme extends InheritedTheme {
iconColor: iconColor,
textColor: textColor,
contentPadding: contentPadding,
tileColor: tileColor,
selectedTileColor: selectedTileColor,
child: child,
);
}
......@@ -148,7 +168,9 @@ class ListTileTheme extends InheritedTheme {
|| selectedColor != oldWidget.selectedColor
|| iconColor != oldWidget.iconColor
|| textColor != oldWidget.textColor
|| contentPadding != oldWidget.contentPadding;
|| contentPadding != oldWidget.contentPadding
|| tileColor != oldWidget.tileColor
|| selectedTileColor != oldWidget.selectedTileColor;
}
}
......@@ -839,14 +861,16 @@ class ListTile extends StatelessWidget {
/// {@macro flutter.widgets.Focus.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;
/// 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;
/// Add a one pixel border in between each tile. If color isn't specified the
......@@ -954,12 +978,20 @@ class ListTile extends StatelessWidget {
: style.copyWith(color: color);
}
Color _tileBackgroundColor() {
if (!selected && tileColor != null)
return tileColor;
Color _tileBackgroundColor(ListTileTheme tileTheme) {
if (!selected) {
if (tileColor != null)
return tileColor;
if (tileTheme?.tileColor != null)
return tileTheme.tileColor;
}
if (selected && selectedTileColor != null)
return selectedTileColor;
if (selected) {
if (selectedTileColor != null)
return selectedTileColor;
if (tileTheme?.selectedTileColor != null)
return tileTheme.selectedTileColor;
}
return Colors.transparent;
}
......@@ -1036,7 +1068,7 @@ class ListTile extends StatelessWidget {
selected: selected,
enabled: enabled,
child: ColoredBox(
color: _tileBackgroundColor(),
color: _tileBackgroundColor(tileTheme),
child: SafeArea(
top: false,
bottom: false,
......
......@@ -1610,4 +1610,86 @@ void main() {
expect(isSelected, isTrue);
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