Stack 中 ListView 顶部的 GestureDetector 会阻止滚动 - Flutter Web
GestureDetector on top of a ListView in a Stack blocks the scroll - Flutter Web
我有一个 Stack,其中首先包含一个 ListView,然后是一个带有 GestureDetector 的透明 Widget,可以单击它。一切正常,但是当我将鼠标放在 GestureDetector 中时,我无法再滚动 ListView,即使将 GestureDetector 的 behavior
属性 设置为 HitTestBehavior.translucent
.
我理解这是因为 GestureDetector 正在吸收它,可能作为拖动事件,但我希望它只检测点击事件并让滚动事件“通过”。我怎样才能在 Flutter 中实现这种行为?
请注意,它仅在使用触控板(我猜是滚轮)滚动时发生,但如果您使用拖放手势滚动列表,则即使您的鼠标悬停在顶部小部件上,滚动也不会停止。
我制作了一个 DartPad,所以你可以在这里 link 自己测试一下:https://dartpad.dev/8d68891da69d661a8129d5adc7727e4c
代码也贴在下面:
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: WhosebugExample()
));
}
class WhosebugExample 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),
),
),
),
],
),
);
}
}
问题不在于 GestureDetector。实际上,文本小部件是阻止 ListView 接收指针事件的小部件。不过,您可以使用 IgnorePointer
.
轻松修复它
IgnorePointer
A widget that is invisible during hit testing.
这将使文本小部件忽略指针事件并让 ListView 接收它们:
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),
),
),
)
我有一个 Stack,其中首先包含一个 ListView,然后是一个带有 GestureDetector 的透明 Widget,可以单击它。一切正常,但是当我将鼠标放在 GestureDetector 中时,我无法再滚动 ListView,即使将 GestureDetector 的 behavior
属性 设置为 HitTestBehavior.translucent
.
我理解这是因为 GestureDetector 正在吸收它,可能作为拖动事件,但我希望它只检测点击事件并让滚动事件“通过”。我怎样才能在 Flutter 中实现这种行为?
请注意,它仅在使用触控板(我猜是滚轮)滚动时发生,但如果您使用拖放手势滚动列表,则即使您的鼠标悬停在顶部小部件上,滚动也不会停止。
我制作了一个 DartPad,所以你可以在这里 link 自己测试一下:https://dartpad.dev/8d68891da69d661a8129d5adc7727e4c
代码也贴在下面:
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: WhosebugExample()
));
}
class WhosebugExample 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),
),
),
),
],
),
);
}
}
问题不在于 GestureDetector。实际上,文本小部件是阻止 ListView 接收指针事件的小部件。不过,您可以使用 IgnorePointer
.
IgnorePointer
A widget that is invisible during hit testing.
这将使文本小部件忽略指针事件并让 ListView 接收它们:
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),
),
),
)