事件与消息通知
一、原始指针事件(触摸事件)
命中测试
- 事件阶段:手指按下、手指移动、手指抬起
- 事件冒泡,无法停止冒泡
Listener 组件:监听原始触摸事件
- onPointerDown:手指按下回调
- onPointerMove:手指移动回调
- onPointerUp:手指抬起回调
- onPointerCancel:触摸事件取消回调
- behavior:决定子组件如何响应命中测试
- 参数 PointerDownEvent、 PointerMoveEvent、 PointerUpEvent 都是PointerEvent的子类,PointerEvent类中包括当前指针的信息
- position:是指针相对于当对于全局坐标的偏移
- localPosition: 是指针相对于本身布局坐标的偏移
- delta:两次指针移动事件(PointerMoveEvent)的距离
- pressure:按压力度,如果手机屏幕不支持压力传感器,则始终为1
- orientation:指针移动方向,是一个角度值
忽略指针事件(阻止子树接收指针事件)
- AbsorbPointer:本身会参与命中测试,即本身是可以接收指针事件的(但其子树不行)
- IgnorePointer:本身不会参与指针事件,即不可以接收指针事件
二、手势识别
- GestureDetector:用于手势识别
- onPanDown:手指按下
- onDoubleTap:双击
- onLongPress:长按
- onPanUpdate:拖动更新
- onPanEnd:滑动结束
- onVerticalDragUpdate:垂直方向拖动
- onScaleUpdate:缩放更新
- GestureRecognizer:通过Listener来将原始指针事件转换为语义手势
三、事件机制
- 事件处理流程
- 深度优先遍历渲染树,依次进行【命中测试】->【事件分发】->【事件清理】
- 命中测试
- 如果当前节点有子节点通过了命中测试或者当前节点自己通过了命中测试,则将当前节点添加到HitTestResult列表中
- 如果通过命中测试,子组件会比父组件会先被加入HitTestResult列表中
- 事件分发
- 遍历HitTestResult列表,调用每个节点的handleEvent 方法
四、手势原理与手势冲突
- 原理待详述
- 解决手势冲突
- 使用 Listener。 竞争只是针对手势的,而 Listener 是监听原始指针事件,原始指针事件并非语义话的手势,所以根本不会走手势竞争的逻辑,相当于跳出了手势识别那套规则。
- 自定义手势识别器( Recognizer)
五、事件总线
- 订阅者模式
- 单例模式
- Dart中实现单例模式的标准做法就是使用static变量+工厂构造函数的方式
//订阅者回调签名 typedef void EventCallback(arg); class EventBus { //私有构造函数 EventBus._internal(); //保存单例 static EventBus _singleton = EventBus._internal(); //工厂构造函数 factory EventBus