Repository: flutter
Issue: Parent onTap Called When Tap Interrupts Scroll Momentum
Labels: framework,f: scrolling,f: gestures,has reproducible steps,P3,workaround available,team-framework,triaged-framework,found in release: 3.19,found in release: 3.20

### Steps to reproduce

1. Create a scrollable (tested and verified with `ListView` and `SingleChildScrollView`)
2. Wrap the scrollable in a tappable (`GestureDetector`, etc)
2. Put a bunch of tappable children inside of the scrollable area
3. Tap on one of the children and note that it's `onTap` is called
4. Fling the scrollable
5. Before the scrollable's momentum subsides, tap on a child in the scrollable

### Expected results

A. The fling stops and the `onTap` of the tapped inner child is called
OR
B. The fling stops and the scrollable consumes the tap so no other `onTap` is called
OR
C. A or B depending on the current momentum of the scroll

This bug is in my prod app and got flagged by a user in a negative store review:
"...9 times out of 10 when you scroll to a different date, it exits the drop down option altogether and you have to start back at the top..."

The core UX problem here is that users don't wait until all the momentum has subsided to tap on a child element and/or they tap on the scrollable to stop the fling momentum). So, if the scrollable is moving slowly, the user expectation is that tapping on the item will work just as if the scrollable were not moving at all. That's why A is preferred. However, I get that there's an ambiguity between whether the user is tapping to stop the scroll momentum or tapping to select an item. That's why C might be the best solution.

[EDIT: I just tested some random applications and this was their behavior:
Google Photos: B
Facebook: B
Twitter: B

So it looks like B is pretty standard and thus probably the actual preferred solution.]

### Actual results

The fling stops and the **outer** tappable region's `onTap` is called.

### Code sample

<details open><summary>Code sample</summary>

```dart
    return MaterialApp(
      home: Scaffold(
        body: GestureDetector(
          onTap: () {
            // If you tap mid-fling this line will run.
            print('outer tap called');
          },
          child: Padding(
            padding: EdgeInsets.all(100),
            child:  ListView.builder(
              itemCount: 100,
              itemBuilder: (context, index) {
                return GestureDetector(
                  onTap: () {
                    // If you tap while the scrollable is still, this line will run.
                    print('tapped on item $index');
                  },
                  child: Container(
                    margin: const EdgeInsets.all(4),
                    padding: const EdgeInsets.all(8),
                    color: Colors.blue,
                    child: Text('Item $index'),
                  ),
                );
              },
            ),
          ),
        ),
      ),
    );
```

</details>


### Screenshots or Video

<details open>
<summary>Screenshots / Video demonstration</summary>

[Upload media here]

</details>


### Logs

<details open><summary>Logs</summary>

```console
Performing hot reload...
Syncing files to device iPhone 15 Pro Max...
flutter: tapped on item 6
flutter: outer tap called
```

</details>


### Flutter Doctor output

<details open><summary>Doctor output</summary>

```console
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.19.1, on macOS 14.3.1 23D60 darwin-arm64, locale en-US)
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 15.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2023.1)
[✓] Connected device (3 available)            
[✓] Network resources

• No issues found!
```

</details>