我错过了什么吗?文档说事件从最里面的子级冒泡到祖先,但下面的代码不会将“拖动”打印到控制台。但它确实打印“点击”。 将 NeverScrollablePhyiscs 应用于 ListView 确实有效,但我想在两个级别上监听该事件。将 HitTestBehavior.translucent 应用于 GestureDetector 不会改变任何内容。
import "package:flutter/material.dart";
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: GestureDetector(
onVerticalDragUpdate: (DragUpdateDetails details) {
print("dragged");
},
onTap: () {
print("tapped");
},
child: ListView.builder(
itemBuilder: (context, index) {
return Container(
padding: EdgeInsets.all(20.0),
child: Text(
"The GestureDetector above me does not react to drag events. Maybe my parent is at fault?"
)
);
},
)
)
);
}
}
您可以使用
Listener
监听原始指针事件
return Scaffold(
body: Listener(onPointerMove: (opm) {
print("onPointerMove .. ${opm.position}");
}, child: ListView.builder(
itemBuilder: (context, index) {
return Container(
padding: EdgeInsets.all(20.0),
child: Text(
"The GestureDetector above me does not react to drag events. Maybe my parent is at fault?"));
},
)));
Listener
小部件对我来说太原始了,它没有拖动开始/结束事件来从其子ListView
捕获。有一个 NotificationListener
可以捕获任何祖先冒泡的内容:
child: NotificationListener(
onNotification: (ScrollNotification notification) {
if (notification is ScrollEndNotification) {
log('NotificationListener: ${notification.dragDetails?.primaryVelocity}');
}
return false; // keep bubbling up
},
child: ListView(
children: [for (int i = 0; i < 10; i++) _tile(i)],
),
),
请注意,如果子组件不是可滚动小部件或者不需要滚动(例如实际的
ListView
但其内容不会浮动在屏幕上),则不会有任何内容冒泡到 NotificationListener
!如果您想捕获所有滚动拖动事件,而不管子内容如何,那么您可能需要同时使用 GestureDetector
(检测不属于祖先的事件)和 NotificationListener
来检测在层次结构中冒泡的事件。
GestureDetector(
// This will trigger if an ancestor doesn't "win" the event
onVerticalDragEnd: (DragEndDetails details) {
log('GestureDetector: ${details.primaryVelocity}');
},
child: NotificationListener(
// This will trigger if an ancestor "wins" the event and bubbles
onNotification: (ScrollNotification notification) {
if (notification is ScrollEndNotification) {
log('NotificationListener: ${notification.dragDetails?.primaryVelocity}');
}
return false; // keep bubbling up
},
child: ListView(
children: [for (int i = 0; i < 10; i++) _tile(i)],
),
),
),