mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Add support for ExpansionPanel custom splash color (#147126)
Relates to https://github.com/flutter/flutter/pull/147098 and https://github.com/flutter/flutter/issues/147097 Aside from fixing the expland/collapse icon color in the other PR, I noticed the splash color on both the icon button and the full expansion panel (if ExpansionPanel.canTapOnHeader is set to true) is just `Theme.of(context).splashColor` on the `InkWell` and `Theme.of(context).highlightColor` on the `IconButton` which may not suit the color scheme of the `ExpansionPanel`, so I have added a custom field `splashColor`, which will effect both the `IconButton` and the full panel `Inkwell`.
This commit is contained in:
parent
cc783cf28a
commit
51168862fb
@ -39,6 +39,8 @@ class ExpandIcon extends StatefulWidget {
|
||||
this.color,
|
||||
this.disabledColor,
|
||||
this.expandedColor,
|
||||
this.splashColor,
|
||||
this.highlightColor,
|
||||
});
|
||||
|
||||
/// Whether the icon is in an expanded state.
|
||||
@ -94,6 +96,20 @@ class ExpandIcon extends StatefulWidget {
|
||||
/// and for [dark theme](https://material.io/design/color/dark-theme.html#ui-application)
|
||||
final Color? expandedColor;
|
||||
|
||||
/// Defines the splash color of the IconButton.
|
||||
///
|
||||
/// If [ThemeData.useMaterial3] is true, this field will be ignored,
|
||||
/// as [IconButton.splashColor] will be ignored, and you should use
|
||||
/// [highlightColor] instead.
|
||||
///
|
||||
/// Defaults to [ThemeData.splashColor].
|
||||
final Color? splashColor;
|
||||
|
||||
/// Defines the highlight color of the IconButton.
|
||||
///
|
||||
/// Defaults to [ThemeData.highlightColor].
|
||||
final Color? highlightColor;
|
||||
|
||||
@override
|
||||
State<ExpandIcon> createState() => _ExpandIconState();
|
||||
}
|
||||
@ -170,6 +186,8 @@ class _ExpandIconState extends State<ExpandIcon> with SingleTickerProviderStateM
|
||||
child: IconButton(
|
||||
padding: widget.padding,
|
||||
iconSize: widget.size,
|
||||
highlightColor: widget.highlightColor,
|
||||
splashColor: widget.splashColor,
|
||||
color: _iconColor,
|
||||
disabledColor: widget.disabledColor,
|
||||
onPressed: widget.onPressed == null ? null : _handlePressed,
|
||||
|
||||
@ -6,6 +6,7 @@ import 'package:flutter/widgets.dart';
|
||||
|
||||
import 'constants.dart';
|
||||
import 'expand_icon.dart';
|
||||
import 'icon_button.dart';
|
||||
import 'ink_well.dart';
|
||||
import 'material_localizations.dart';
|
||||
import 'mergeable_material.dart';
|
||||
@ -80,6 +81,8 @@ class ExpansionPanel {
|
||||
this.isExpanded = false,
|
||||
this.canTapOnHeader = false,
|
||||
this.backgroundColor,
|
||||
this.splashColor,
|
||||
this.highlightColor,
|
||||
});
|
||||
|
||||
/// The widget builder that builds the expansion panels' header.
|
||||
@ -95,6 +98,28 @@ class ExpansionPanel {
|
||||
/// Defaults to false.
|
||||
final bool isExpanded;
|
||||
|
||||
/// Defines the splash color of the panel if [canTapOnHeader] is true,
|
||||
/// or the splash color of the expand/collapse IconButton if [canTapOnHeader]
|
||||
/// is false.
|
||||
///
|
||||
/// If [canTapOnHeader] is false, and [ThemeData.useMaterial3] is
|
||||
/// true, this field will be ignored, as [IconButton.splashColor]
|
||||
/// will be ignored, and you should use [highlightColor] instead.
|
||||
///
|
||||
/// If this is null, then the icon button will use its default splash color
|
||||
/// [ThemeData.splashColor], and the panel will use its default splash color
|
||||
/// [ThemeData.splashColor] (if [canTapOnHeader] is true).
|
||||
final Color? splashColor;
|
||||
|
||||
/// Defines the highlight color of the panel if [canTapOnHeader] is true, or
|
||||
/// the highlight color of the expand/collapse IconButton if [canTapOnHeader]
|
||||
/// is false.
|
||||
///
|
||||
/// If this is null, then the icon button will use its default highlight color
|
||||
/// [ThemeData.highlightColor], and the panel will use its default highlight
|
||||
/// color [ThemeData.highlightColor] (if [canTapOnHeader] is true).
|
||||
final Color? highlightColor;
|
||||
|
||||
/// Whether tapping on the panel's header will expand/collapse it.
|
||||
///
|
||||
/// Defaults to false.
|
||||
@ -125,6 +150,8 @@ class ExpansionPanelRadio extends ExpansionPanel {
|
||||
required super.body,
|
||||
super.canTapOnHeader,
|
||||
super.backgroundColor,
|
||||
super.splashColor,
|
||||
super.highlightColor,
|
||||
});
|
||||
|
||||
/// The value that uniquely identifies a radio panel so that the currently
|
||||
@ -366,6 +393,8 @@ class _ExpansionPanelListState extends State<ExpansionPanelList> {
|
||||
disabledColor: child.canTapOnHeader ? widget.expandIconColor : null,
|
||||
isExpanded: _isChildExpanded(index),
|
||||
padding: _kExpandIconPadding,
|
||||
splashColor: child.splashColor,
|
||||
highlightColor: child.highlightColor,
|
||||
onPressed: !child.canTapOnHeader
|
||||
? (bool isExpanded) => _handlePressed(isExpanded, index)
|
||||
: null,
|
||||
@ -399,6 +428,8 @@ class _ExpansionPanelListState extends State<ExpansionPanelList> {
|
||||
if (child.canTapOnHeader) {
|
||||
header = MergeSemantics(
|
||||
child: InkWell(
|
||||
splashColor: child.splashColor,
|
||||
highlightColor: child.highlightColor,
|
||||
onTap: () => _handlePressed(_isChildExpanded(index), index),
|
||||
child: header,
|
||||
),
|
||||
|
||||
@ -1948,6 +1948,74 @@ void main() {
|
||||
}
|
||||
});
|
||||
|
||||
testWidgets('Ensure IconButton splashColor and highlightColor are correctly set when canTapOnHeader is false', (WidgetTester tester) async {
|
||||
const Color expectedSplashColor = Colors.green;
|
||||
const Color expectedHighlightColor = Colors.yellow;
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SingleChildScrollView(
|
||||
child: ExpansionPanelList(
|
||||
children: <ExpansionPanel>[
|
||||
ExpansionPanel(
|
||||
headerBuilder: (BuildContext context, bool isExpanded) {
|
||||
return const ListTile(title: Text('Panel 1'));
|
||||
},
|
||||
body: const ListTile(title: Text('Content for Panel 1')),
|
||||
splashColor: expectedSplashColor,
|
||||
highlightColor: expectedHighlightColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
await tester.tap(find.text('Panel 1'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final IconButton iconButton = tester.widget(find.byType(IconButton).first);
|
||||
expect(iconButton.splashColor, expectedSplashColor);
|
||||
expect(iconButton.highlightColor, expectedHighlightColor);
|
||||
});
|
||||
|
||||
testWidgets('Ensure InkWell splashColor and highlightColor are correctly set when canTapOnHeader is true', (WidgetTester tester) async {
|
||||
const Color expectedSplashColor = Colors.green;
|
||||
const Color expectedHighlightColor = Colors.yellow;
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SingleChildScrollView(
|
||||
child: ExpansionPanelList(
|
||||
children: <ExpansionPanel>[
|
||||
ExpansionPanel(
|
||||
canTapOnHeader: true,
|
||||
headerBuilder: (BuildContext context, bool isExpanded) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
alignment: Alignment.centerLeft,
|
||||
child: const Text('Panel 1'),
|
||||
);
|
||||
},
|
||||
body: const ListTile(title: Text('Content for Panel 1')),
|
||||
splashColor: expectedSplashColor,
|
||||
highlightColor: expectedHighlightColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final Finder inkWellFinder = find.descendant(
|
||||
of: find.byType(ExpansionPanelList),
|
||||
matching: find.byWidgetPredicate((Widget widget) =>
|
||||
widget is InkWell && widget.onTap != null)
|
||||
);
|
||||
|
||||
final InkWell inkWell = tester.widget<InkWell>(inkWellFinder);
|
||||
expect(inkWell.splashColor, expectedSplashColor);
|
||||
expect(inkWell.highlightColor, expectedHighlightColor);
|
||||
});
|
||||
|
||||
testWidgets('ExpandIcon.disabledColor uses expandIconColor color when canTapOnHeader is true', (WidgetTester tester) async {
|
||||
const Color expandIconColor = Color(0xff0000ff);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user