Unverified Commit dc6ab626 authored by Hans Muller's avatar Hans Muller Committed by GitHub

Fixed one-frame InkWell overlay color problem on unhover (#111112)

parent 5cd37788
......@@ -857,22 +857,6 @@ class _InkResponseState extends State<_InkResponseStateWidget>
@override
bool get wantKeepAlive => highlightsExist || (_splashes != null && _splashes!.isNotEmpty);
Color getHighlightColorForType(_HighlightType type) {
final ThemeData theme = Theme.of(context);
final Color? resolvedOverlayColor = widget.overlayColor?.resolve(statesController.value);
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 resolvedOverlayColor ?? widget.highlightColor ?? theme.highlightColor;
case _HighlightType.focus:
return resolvedOverlayColor ?? widget.focusColor ?? theme.focusColor;
case _HighlightType.hover:
return resolvedOverlayColor ?? widget.hoverColor ?? theme.hoverColor;
}
}
Duration getFadeDurationForType(_HighlightType type) {
switch (type) {
case _HighlightType.pressed:
......@@ -911,13 +895,30 @@ class _InkResponseState extends State<_InkResponseStateWidget>
if (value == (highlight != null && highlight.active)) {
return;
}
if (value) {
if (highlight == null) {
Color? resolvedOverlayColor = widget.overlayColor?.resolve(statesController.value);
if (resolvedOverlayColor == null) {
// Use the backwards compatible defaults
final ThemeData theme = Theme.of(context);
switch (type) {
case _HighlightType.pressed:
resolvedOverlayColor = widget.highlightColor ?? theme.highlightColor;
break;
case _HighlightType.focus:
resolvedOverlayColor = widget.focusColor ?? theme.focusColor;
break;
case _HighlightType.hover:
resolvedOverlayColor = widget.hoverColor ?? theme.hoverColor;
break;
}
}
final RenderBox referenceBox = context.findRenderObject()! as RenderBox;
_highlights[type] = InkHighlight(
controller: Material.of(context)!,
referenceBox: referenceBox,
color: getHighlightColorForType(type),
color: resolvedOverlayColor,
shape: widget.highlightShape,
radius: widget.radius,
borderRadius: widget.borderRadius,
......@@ -1159,6 +1160,25 @@ class _InkResponseState extends State<_InkResponseStateWidget>
Widget build(BuildContext context) {
assert(widget.debugCheckContext(context));
super.build(context); // See AutomaticKeepAliveClientMixin.
Color getHighlightColorForType(_HighlightType type) {
const Set<MaterialState> pressed = <MaterialState>{MaterialState.pressed};
const Set<MaterialState> focused = <MaterialState>{MaterialState.focused};
const Set<MaterialState> hovered = <MaterialState>{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.overlayColor?.resolve(pressed) ?? widget.highlightColor ?? theme.highlightColor;
case _HighlightType.focus:
return widget.overlayColor?.resolve(focused) ?? widget.focusColor ?? theme.focusColor;
case _HighlightType.hover:
return widget.overlayColor?.resolve(hovered) ?? widget.hoverColor ?? theme.hoverColor;
}
}
for (final _HighlightType type in _highlights.keys) {
_highlights[type]?.color = getHighlightColorForType(type);
}
......
......@@ -1556,4 +1556,42 @@ void main() {
expect(tapCount, 3);
expect(pressedCount, 2);
});
testWidgets('ink well overlayColor opacity fades from 0xff when hover ends', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/110266
await tester.pumpWidget(Material(
child: Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: SizedBox(
width: 100,
height: 100,
child: InkWell(
overlayColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
if (states.contains(MaterialState.hovered)) {
return const Color(0xff00ff00);
}
return null;
}),
onTap: () { },
onLongPress: () { },
onHover: (bool hover) { },
),
),
),
),
));
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
await gesture.addPointer();
await gesture.moveTo(tester.getCenter(find.byType(SizedBox)));
await tester.pumpAndSettle();
await gesture.moveTo(const Offset(10, 10)); // fade out the overlay
await tester.pump(); // trigger the fade out animation
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
// Fadeout begins with the MaterialStates.hovered overlay color
expect(inkFeatures, paints..rect(rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0), color: const Color(0xff00ff00)));
// 50ms fadeout is 50% complete, overlay color alpha goes from 0xff to 0x80
await tester.pump(const Duration(milliseconds: 25));
expect(inkFeatures, paints..rect(rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0), color: const Color(0x8000ff00)));
});
}
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