GestureDetector on top of a ListView in a Stack blocks the scroll - Flutter Web
Asked Answered
W

1

6

I have a Stack containing first a ListView, then a transparent Widget with a GestureDetector to click on it. Everything works fine but when I put the mouse inside the GestureDetector I can't scroll the ListView anymore, even when setting the behavior property of the GestureDetector to HitTestBehavior.translucent.

I understand it is because the GestureDetector is absorbing it, maybe as a drag event, but I would like it to only detect the tap event and let the scrolling event go "through". How could I achieve this behavior in Flutter?

Note that it only happens when scrolling using the trackpad (and I guess a scroll wheel), but if you scroll the list with a drag&drop gesture then the scroll will not stop even if your mouse hovers the top widget.

I've made a DartPad so you can test it for yourself at this link : https://dartpad.dev/8d68891da69d661a8129d5adc7727e4c

The code is also pasted below :

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: StackOverflowExample()
    ));
}

class StackOverflowExample extends StatelessWidget {
  Widget _buildListItem() {
    return Container(
      margin: const EdgeInsets.symmetric(vertical: 10),
      height: 100,
      color: Colors.blue[100],
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          ListView.builder(
            itemCount: 20,
            itemBuilder: (_, __) => _buildListItem(),
          ),
          Center(
            child: GestureDetector(
              behavior: HitTestBehavior.translucent,
              onTap: () => print('tap'),
              child: const Text(
                'Hover me and\ntry to scroll\nthe listview',
                style: TextStyle(fontSize: 50, fontWeight: FontWeight.bold),
              ),
            ),
          ),
        ],
      ),
    );
  }
}
Waistcloth answered 16/8, 2021 at 15:37 Comment(0)
T
9

The problem is not with GestureDetector. Actually, the Text widget is the one that prevents the ListView from receiving pointer events. Nevertheless, you can easily fix it using IgnorePointer.

IgnorePointer

A widget that is invisible during hit testing.

This will make the Text widget ignore the pointer events and let the ListView receive them instead:

GestureDetector(
  behavior: HitTestBehavior.translucent,
  onTap: () => print('tap'),
  child: IgnorePointer( // You insert it right here above the Text widget
    child: const Text(
      'Hover me and\ntry to scroll\nthe listview',
      style: TextStyle(fontSize: 50, fontWeight: FontWeight.bold),
    ),
  ),
)
Triune answered 16/8, 2021 at 16:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.