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),
),
),
),
],
),
);
}
}
CodePudding user response:
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),
),
),
)