m93*_*93a 10 event-bubbling event-propagation flutter
我正在 Flutter 中制作一个 Android 应用程序,我想添加一个交互式小部件来侦听原始指针事件并对它们做出反应。使用小部件很容易做到这一点Listener
:
class _MyWidget extends State<MyWidget> {\n @override\n build(BuildContext ctx) {\n return Listener(\n onPointerMove: (event) {\n event.delta // use this to do some magic...\n },\n child: ...\n );\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n然而,这个小部件是在 a 内呈现的PageView
,它允许用户滑动以更改页面。这是我不想摆脱 \xe2\x80\x93 的行为,除了用户滑过的时间MyWidget
。由于MyWidget
需要用户触摸并拖动,我不希望他们意外导航到不同的页面。
在浏览器中,这实现起来非常简单,我只需调用event.stopPropagation()
,事件就不会从其MyWidget
祖先传播(即冒泡) PageView
。如何停止 Flutter 中事件的传播?
理论上,我可以MyWidget
设置应用程序状态,并PageView
在我滑动时使用它来禁用MyWidget
。然而,这将违背 Flutter 小部件的自然数据流:它需要我在多个位置添加回调,并使所有小部件更加交织在一起且可重用性降低。我更愿意防止事件在本地冒泡。
编辑:我尝试过使用AbsorbPointer
,但它似乎在错误的方向上“阻止传播”。它阻止 的所有子级接收AbsorbPointer
指针事件。我想要的是完全相反的 \xe2\x80\x93 阻止子级上的指针事件传播到其祖先。
use*_*613 15
在 Flutter 中,通常只有 1 个 widget 响应用户触摸事件,而不是触摸位置处的所有部件一起响应。为了确定哪个小部件应该响应触摸事件,Flutter 使用一种称为“手势竞技场”的东西来确定“获胜者”。
Listener
是一个原始的监听小部件,不会在“手势竞技场”中竞争,因此即使在技术上更接近用户(并且会获胜),底层PageView
仍将在“手势竞技场”中“获胜” 。Listener
另一方面,更先进的(较少原始的)小部件,例如GestureDetector
确实进入“手势竞技场”竞争,并且会“获胜”,从而导致PageView
在竞技场中“失败”,因此页面视图不会移动。
例如,尝试将此代码放入 a 中PageView
并拖动它:
GestureDetector(
onHorizontalDragUpdate: (DragUpdateDetails details) {
print('on Horizontal Drag Update');
},
onVerticalDragUpdate: (DragUpdateDetails details) {
print('on Vertical Drag Update');
},
child: Container(
width: 100,
height: 100,
color: Colors.red,
),
)
Run Code Online (Sandbox Code Playgroud)
您应该注意到PageView
不再滚动。
但是,根据 的滚动轴PageView
(无论是水平滚动还是垂直滚动),删除上面的事件之一GestureDetector
(例如删除onHorizontalDragUpdate
水平滚动的事件侦听器PageView
)将使 能够PageView
再次滚动。这是因为水平滑动和垂直滑动是进入不同手势区域的“非冲突事件”。
那么,回到你原来的问题,你可以使用这些“更高级”的小部件重写你的业务逻辑,而不是处理原始级别的数据吗Listener
?如果是这样,框架就会为你解决问题。
Listener
如果您出于某种原因必须使用,我为您提供了另一种可能的解决方法:在PageView
小部件中,您可以传入physics: const NeverScrollableScrollPhysics()
以使其停止滚动。因此,您也许可以监视触摸事件,并相应地设置/清除属性。本质上,在“触地”时,锁定PageView
,在“触地”时释放它。
归档时间: |
|
查看次数: |
3915 次 |
最近记录: |