From 7d4497a1b2778d975bdfa0649eb84adfc481efc8 Mon Sep 17 00:00:00 2001 From: Hans Muller Date: Tue, 11 Jan 2022 08:23:01 -0800 Subject: [PATCH] InkWell.overlayColor is now resolved against MaterialState.pressed (#96435) --- .../flutter/lib/src/material/ink_well.dart | 19 ++++++----- .../flutter/test/material/ink_well_test.dart | 34 +++++++++++++++++++ 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/packages/flutter/lib/src/material/ink_well.dart b/packages/flutter/lib/src/material/ink_well.dart index 5c13c053adb..dbac66f9852 100644 --- a/packages/flutter/lib/src/material/ink_well.dart +++ b/packages/flutter/lib/src/material/ink_well.dart @@ -483,11 +483,12 @@ class InkResponse extends StatelessWidget { /// Defines the ink response focus, hover, and splash colors. /// /// This default null property can be used as an alternative to - /// [focusColor], [hoverColor], and [splashColor]. If non-null, - /// it is resolved against one of [MaterialState.focused], - /// [MaterialState.hovered], and [MaterialState.pressed]. It's - /// convenient to use when the parent widget can pass along its own - /// MaterialStateProperty value for the overlay color. + /// [focusColor], [hoverColor], [highlightColor], and + /// [splashColor]. If non-null, it is resolved against one of + /// [MaterialState.focused], [MaterialState.hovered], and + /// [MaterialState.pressed]. It's convenient to use when the parent + /// widget can pass along its own MaterialStateProperty value for + /// the overlay color. /// /// [MaterialState.pressed] triggers a ripple (an ink splash), per /// the current Material Design spec. The [overlayColor] doesn't map @@ -799,19 +800,21 @@ class _InkResponseState extends State<_InkResponseStateWidget> bool get wantKeepAlive => highlightsExist || (_splashes != null && _splashes!.isNotEmpty); Color getHighlightColorForType(_HighlightType type) { + const Set pressed = {MaterialState.pressed}; const Set focused = {MaterialState.focused}; const Set hovered = {MaterialState.hovered}; + final ThemeData theme = Theme.of(context); switch (type) { // The pressed state triggers a ripple (ink splash), per the current // Material Design spec. A separate highlight is no longer used. // See https://material.io/design/interaction/states.html#pressed case _HighlightType.pressed: - return widget.highlightColor ?? Theme.of(context).highlightColor; + return widget.overlayColor?.resolve(pressed) ?? widget.highlightColor ?? theme.highlightColor; case _HighlightType.focus: - return widget.overlayColor?.resolve(focused) ?? widget.focusColor ?? Theme.of(context).focusColor; + return widget.overlayColor?.resolve(focused) ?? widget.focusColor ?? theme.focusColor; case _HighlightType.hover: - return widget.overlayColor?.resolve(hovered) ?? widget.hoverColor ?? Theme.of(context).hoverColor; + return widget.overlayColor?.resolve(hovered) ?? widget.hoverColor ?? theme.hoverColor; } } diff --git a/packages/flutter/test/material/ink_well_test.dart b/packages/flutter/test/material/ink_well_test.dart index 55d67a0c08d..f03bb3a8c8d 100644 --- a/packages/flutter/test/material/ink_well_test.dart +++ b/packages/flutter/test/material/ink_well_test.dart @@ -292,6 +292,40 @@ void main() { ); }); + testWidgets('ink well changes color on pressed with overlayColor', (WidgetTester tester) async { + const Color pressedColor = Color(0xffdd00ff); + + await tester.pumpWidget(Material( + child: Directionality( + textDirection: TextDirection.ltr, + child: Container( + alignment: Alignment.topLeft, + child: SizedBox( + width: 100, + height: 100, + child: InkWell( + splashFactory: NoSplash.splashFactory, + overlayColor: MaterialStateProperty.resolveWith((Set states) { + if (states.contains(MaterialState.pressed)) { + return pressedColor; + } + return const Color(0xffbadbad); // Shouldn't happen. + }), + onTap: () { }, + ), + ), + ), + ), + )); + await tester.pumpAndSettle(); + final TestGesture gesture = await tester.startGesture(tester.getRect(find.byType(InkWell)).center); + final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures'); + expect(inkFeatures, paints..rect(rect: const Rect.fromLTRB(0, 0, 100, 100), color: pressedColor.withAlpha(0))); + await tester.pumpAndSettle(); // Let the press highlight animation finish. + expect(inkFeatures, paints..rect(rect: const Rect.fromLTRB(0, 0, 100, 100), color: pressedColor)); + await gesture.up(); + }); + testWidgets('ink response splashColor matches splashColor parameter', (WidgetTester tester) async { FocusManager.instance.highlightStrategy = FocusHighlightStrategy.alwaysTouch; final FocusNode focusNode = FocusNode(debugLabel: 'Ink Focus');