Fix InkWell highlight and splash sometimes persists (#100880)

diff --git a/packages/flutter/lib/src/material/ink_well.dart b/packages/flutter/lib/src/material/ink_well.dart
index e90fb23..6192ec5 100644
--- a/packages/flutter/lib/src/material/ink_well.dart
+++ b/packages/flutter/lib/src/material/ink_well.dart
@@ -769,12 +769,12 @@
   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 @@
   void _handleTapDown(TapDownDetails details) {
     if (_anyChildInkResponsePressed)
       return;
-    _startSplash(details: details);
+    _startNewSplash(details: details);
     widget.onTapDown?.call(details);
   }
 
@@ -974,7 +974,7 @@
     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 @@
     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 @@
   void _handleDoubleTap() {
     _currentSplash?.confirm();
     _currentSplash = null;
+    updateHighlight(_HighlightType.pressed, value: false);
     widget.onDoubleTap?.call();
   }
 
diff --git a/packages/flutter/test/material/ink_well_test.dart b/packages/flutter/test/material/ink_well_test.dart
index 0d2146f..7957916 100644
--- a/packages/flutter/test/material/ink_well_test.dart
+++ b/packages/flutter/test/material/ink_well_test.dart
@@ -1424,4 +1424,90 @@
       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));
+  });
 }