Unverified Commit 05759325 authored by Bruno Leroux's avatar Bruno Leroux Committed by GitHub

Fix InkWell highlight and splash sometimes persists (#100880)

parent cb968c5f
...@@ -769,12 +769,12 @@ class _InkResponseState extends State<_InkResponseStateWidget> ...@@ -769,12 +769,12 @@ class _InkResponseState extends State<_InkResponseStateWidget>
bool get _anyChildInkResponsePressed => _activeChildren.isNotEmpty; bool get _anyChildInkResponsePressed => _activeChildren.isNotEmpty;
void _simulateTap([Intent? intent]) { void _simulateTap([Intent? intent]) {
_startSplash(context: context); _startNewSplash(context: context);
_handleTap(); _handleTap();
} }
void _simulateLongPress() { void _simulateLongPress() {
_startSplash(context: context); _startNewSplash(context: context);
_handleLongPress(); _handleLongPress();
} }
...@@ -966,7 +966,7 @@ class _InkResponseState extends State<_InkResponseStateWidget> ...@@ -966,7 +966,7 @@ class _InkResponseState extends State<_InkResponseStateWidget>
void _handleTapDown(TapDownDetails details) { void _handleTapDown(TapDownDetails details) {
if (_anyChildInkResponsePressed) if (_anyChildInkResponsePressed)
return; return;
_startSplash(details: details); _startNewSplash(details: details);
widget.onTapDown?.call(details); widget.onTapDown?.call(details);
} }
...@@ -974,7 +974,7 @@ class _InkResponseState extends State<_InkResponseStateWidget> ...@@ -974,7 +974,7 @@ class _InkResponseState extends State<_InkResponseStateWidget>
widget.onTapUp?.call(details); widget.onTapUp?.call(details);
} }
void _startSplash({TapDownDetails? details, BuildContext? context}) { void _startNewSplash({TapDownDetails? details, BuildContext? context}) {
assert(details != null || context != null); assert(details != null || context != null);
final Offset globalPosition; final Offset globalPosition;
...@@ -988,6 +988,7 @@ class _InkResponseState extends State<_InkResponseStateWidget> ...@@ -988,6 +988,7 @@ class _InkResponseState extends State<_InkResponseStateWidget>
final InteractiveInkFeature splash = _createInkFeature(globalPosition); final InteractiveInkFeature splash = _createInkFeature(globalPosition);
_splashes ??= HashSet<InteractiveInkFeature>(); _splashes ??= HashSet<InteractiveInkFeature>();
_splashes!.add(splash); _splashes!.add(splash);
_currentSplash?.cancel();
_currentSplash = splash; _currentSplash = splash;
updateKeepAlive(); updateKeepAlive();
updateHighlight(_HighlightType.pressed, value: true); updateHighlight(_HighlightType.pressed, value: true);
...@@ -1014,6 +1015,7 @@ class _InkResponseState extends State<_InkResponseStateWidget> ...@@ -1014,6 +1015,7 @@ class _InkResponseState extends State<_InkResponseStateWidget>
void _handleDoubleTap() { void _handleDoubleTap() {
_currentSplash?.confirm(); _currentSplash?.confirm();
_currentSplash = null; _currentSplash = null;
updateHighlight(_HighlightType.pressed, value: false);
widget.onDoubleTap?.call(); widget.onDoubleTap?.call();
} }
......
...@@ -1424,4 +1424,90 @@ void main() { ...@@ -1424,4 +1424,90 @@ void main() {
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
)); ));
}); });
testWidgets('InkWell highlight should not survive after [onTapDown, onDoubleTap] sequence', (WidgetTester tester) async {
final List<String> log = <String>[];
await tester.pumpWidget(Directionality(
textDirection: TextDirection.ltr,
child: Material(
child: Center(
child: InkWell(
onTap: () {
log.add('tap');
},
onDoubleTap: () {
log.add('double-tap');
},
onTapDown: (TapDownDetails details) {
log.add('tap-down');
},
onTapCancel: () {
log.add('tap-cancel');
},
),
),
),
));
final Offset taplocation = tester.getRect(find.byType(InkWell)).center;
final TestGesture gesture = await tester.startGesture(taplocation);
await tester.pump(const Duration(milliseconds: 100));
expect(log, equals(<String>['tap-down']));
await gesture.up();
await tester.pump(const Duration(milliseconds: 100));
await tester.tap(find.byType(InkWell));
await tester.pump(const Duration(milliseconds: 100));
expect(log, equals(<String>['tap-down', 'double-tap']));
await tester.pumpAndSettle();
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
expect(inkFeatures, paintsExactlyCountTimes(#drawRect, 0));
});
testWidgets('InkWell splash should not survive after [onTapDown, onTapDown, onTapCancel, onDoubleTap] sequence', (WidgetTester tester) async {
final List<String> log = <String>[];
await tester.pumpWidget(Directionality(
textDirection: TextDirection.ltr,
child: Material(
child: Center(
child: InkWell(
onTap: () {
log.add('tap');
},
onDoubleTap: () {
log.add('double-tap');
},
onTapDown: (TapDownDetails details) {
log.add('tap-down');
},
onTapCancel: () {
log.add('tap-cancel');
},
),
),
),
));
final Offset tapLocation = tester.getRect(find.byType(InkWell)).center;
final TestGesture gesture1 = await tester.startGesture(tapLocation);
await tester.pump(const Duration(milliseconds: 100));
expect(log, equals(<String>['tap-down']));
await gesture1.up();
await tester.pump(const Duration(milliseconds: 100));
final TestGesture gesture2 = await tester.startGesture(tapLocation);
await tester.pump(const Duration(milliseconds: 100));
expect(log, equals(<String>['tap-down', 'tap-down']));
await gesture2.up();
await tester.pump(const Duration(milliseconds: 100));
expect(log, equals(<String>['tap-down', 'tap-down', 'tap-cancel', 'double-tap']));
await tester.pumpAndSettle();
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
expect(inkFeatures, paintsExactlyCountTimes(#drawCircle, 0));
});
} }
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