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>
bool get _anyChildInkResponsePressed => _activeChildren.isNotEmpty;
void _simulateTap([Intent? intent]) {
_startSplash(context: context);
_startNewSplash(context: context);
_handleTap();
}
void _simulateLongPress() {
_startSplash(context: context);
_startNewSplash(context: context);
_handleLongPress();
}
......@@ -966,7 +966,7 @@ class _InkResponseState extends State<_InkResponseStateWidget>
void _handleTapDown(TapDownDetails details) {
if (_anyChildInkResponsePressed)
return;
_startSplash(details: details);
_startNewSplash(details: details);
widget.onTapDown?.call(details);
}
......@@ -974,7 +974,7 @@ class _InkResponseState extends State<_InkResponseStateWidget>
widget.onTapUp?.call(details);
}
void _startSplash({TapDownDetails? details, BuildContext? context}) {
void _startNewSplash({TapDownDetails? details, BuildContext? context}) {
assert(details != null || context != null);
final Offset globalPosition;
......@@ -988,6 +988,7 @@ class _InkResponseState extends State<_InkResponseStateWidget>
final InteractiveInkFeature splash = _createInkFeature(globalPosition);
_splashes ??= HashSet<InteractiveInkFeature>();
_splashes!.add(splash);
_currentSplash?.cancel();
_currentSplash = splash;
updateKeepAlive();
updateHighlight(_HighlightType.pressed, value: true);
......@@ -1014,6 +1015,7 @@ class _InkResponseState extends State<_InkResponseStateWidget>
void _handleDoubleTap() {
_currentSplash?.confirm();
_currentSplash = null;
updateHighlight(_HighlightType.pressed, value: false);
widget.onDoubleTap?.call();
}
......
......@@ -1424,4 +1424,90 @@ void main() {
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