Skip to content

Commit 3c3c9a1

Browse files
authored
[M3] Add ListTile's iconColor property support for icon buttons (#120075)
* add icon button property override * list tile changes * add imports * add newlines * whitespace
1 parent 47a0674 commit 3c3c9a1

File tree

2 files changed

+67
-15
lines changed

2 files changed

+67
-15
lines changed

packages/flutter/lib/src/material/list_tile.dart

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import 'colors.dart';
1212
import 'constants.dart';
1313
import 'debug.dart';
1414
import 'divider.dart';
15+
import 'icon_button.dart';
16+
import 'icon_button_theme.dart';
1517
import 'ink_decoration.dart';
1618
import 'ink_well.dart';
1719
import 'list_tile_theme.dart';
@@ -692,6 +694,9 @@ class ListTile extends StatelessWidget {
692694
?? resolveColor(theme.listTileTheme.textColor, theme.listTileTheme.selectedColor, theme.listTileTheme.textColor)
693695
?? resolveColor(defaults.textColor, defaults.selectedColor, defaults.textColor, theme.disabledColor);
694696
final IconThemeData iconThemeData = IconThemeData(color: effectiveIconColor);
697+
final IconButtonThemeData iconButtonThemeData = IconButtonThemeData(
698+
style: IconButton.styleFrom(foregroundColor: effectiveIconColor),
699+
);
695700

696701
TextStyle? leadingAndTrailingStyle;
697702
if (leading != null || trailing != null) {
@@ -791,21 +796,24 @@ class ListTile extends StatelessWidget {
791796
minimum: resolvedContentPadding,
792797
child: IconTheme.merge(
793798
data: iconThemeData,
794-
child: _ListTile(
795-
leading: leadingIcon,
796-
title: titleText,
797-
subtitle: subtitleText,
798-
trailing: trailingIcon,
799-
isDense: _isDenseLayout(theme, tileTheme),
800-
visualDensity: visualDensity ?? tileTheme.visualDensity ?? theme.visualDensity,
801-
isThreeLine: isThreeLine,
802-
textDirection: textDirection,
803-
titleBaselineType: titleStyle.textBaseline ?? defaults.titleTextStyle!.textBaseline!,
804-
subtitleBaselineType: subtitleStyle?.textBaseline ?? defaults.subtitleTextStyle!.textBaseline!,
805-
horizontalTitleGap: horizontalTitleGap ?? tileTheme.horizontalTitleGap ?? 16,
806-
minVerticalPadding: minVerticalPadding ?? tileTheme.minVerticalPadding ?? defaults.minVerticalPadding!,
807-
minLeadingWidth: minLeadingWidth ?? tileTheme.minLeadingWidth ?? defaults.minLeadingWidth!,
808-
material3: theme.useMaterial3,
799+
child: IconButtonTheme(
800+
data: iconButtonThemeData,
801+
child: _ListTile(
802+
leading: leadingIcon,
803+
title: titleText,
804+
subtitle: subtitleText,
805+
trailing: trailingIcon,
806+
isDense: _isDenseLayout(theme, tileTheme),
807+
visualDensity: visualDensity ?? tileTheme.visualDensity ?? theme.visualDensity,
808+
isThreeLine: isThreeLine,
809+
textDirection: textDirection,
810+
titleBaselineType: titleStyle.textBaseline ?? defaults.titleTextStyle!.textBaseline!,
811+
subtitleBaselineType: subtitleStyle?.textBaseline ?? defaults.subtitleTextStyle!.textBaseline!,
812+
horizontalTitleGap: horizontalTitleGap ?? tileTheme.horizontalTitleGap ?? 16,
813+
minVerticalPadding: minVerticalPadding ?? tileTheme.minVerticalPadding ?? defaults.minVerticalPadding!,
814+
minLeadingWidth: minLeadingWidth ?? tileTheme.minLeadingWidth ?? defaults.minLeadingWidth!,
815+
material3: theme.useMaterial3,
816+
),
809817
),
810818
),
811819
),

packages/flutter/test/material/list_tile_test.dart

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2150,6 +2150,50 @@ void main() {
21502150
expect(iconColor(leadingKey), selectedColor);
21512151
});
21522152

2153+
testWidgets('ListTile.iconColor respects iconColor property with icon buttons Material 3 in presence of IconButtonTheme override', (WidgetTester tester) async {
2154+
const Color iconButtonThemeColor = Colors.blue;
2155+
const Color listTileIconColor = Colors.green;
2156+
const Icon leadingIcon = Icon(Icons.favorite);
2157+
const Icon trailingIcon = Icon(Icons.close);
2158+
2159+
Widget buildFrame() {
2160+
return MaterialApp(
2161+
theme: ThemeData(
2162+
useMaterial3: true,
2163+
iconButtonTheme: IconButtonThemeData(
2164+
style: IconButton.styleFrom(
2165+
foregroundColor: iconButtonThemeColor,
2166+
),
2167+
),
2168+
),
2169+
home: Material(
2170+
child: Center(
2171+
child: Builder(
2172+
builder: (BuildContext context) {
2173+
return ListTile(
2174+
iconColor: listTileIconColor,
2175+
leading: IconButton(icon: leadingIcon, onPressed: () {}),
2176+
trailing: IconButton(icon: trailingIcon, onPressed: () {}),
2177+
);
2178+
},
2179+
),
2180+
),
2181+
),
2182+
);
2183+
}
2184+
2185+
TextStyle? getIconStyle(WidgetTester tester, IconData icon) =>
2186+
tester.widget<RichText>(find.descendant(
2187+
of: find.byIcon(icon),
2188+
matching: find.byType(RichText),
2189+
),
2190+
).text.style;
2191+
2192+
await tester.pumpWidget(buildFrame());
2193+
expect(getIconStyle(tester, leadingIcon.icon!)?.color, listTileIconColor);
2194+
expect(getIconStyle(tester, trailingIcon.icon!)?.color, listTileIconColor);
2195+
});
2196+
21532197
testWidgets('ListTile.dense does not throw assertion', (WidgetTester tester) async {
21542198
// This is a regression test for https://github.com/flutter/flutter/pull/116908
21552199

0 commit comments

Comments
 (0)