Flutter-事件监听
指针事件
Pointer 代表的是人机界面交互的原始数据。一共有四种指针事件:
- PointerDownEvent 指针在特定位置与屏暮接触
- pointerMoveEvent 指针从屏幕的一个位置移动到另外一个位置
- pointerUpEvent 指针与屏幕停止接触
- PolntercancelEvent 指针因为一些特殊情况被取消
Pointer的原理
- 在指针落下时,框架做了一个hitTest 的操作,确定与屏幕发生接触的位置上有哪些Widget 以及分发给最内部的组件去响应;
- 事件会沿着最内部的组件向组件树的根冒泡分发;
- 并且不存在用于取消或者停止指针事件进一步分发的机制
原始指针事件使用Listener来监听
Center(
child: Listener(
onPointerDown: (event) {
print("指针按下:$event");
},
onPointerMove: (event){
print("指针移动:$event");
},
onPointerUp: (event){
print("指针抬起:$event");
},
child: Container(
width: 200,
height: 200,
color: Colors.red,
),
)
),
手势识别 Gesture
Gesture分层非常多的种类:
点击:
- onTapDown:用户发生手指按下的操作
- onTapup:用户发生手指抬起的操作
- onTap:用户点击事件完成
- onTapCancel:事件按下过程中被取消
双击:
- onDoubleTap:快速点击了两次
长按:
- onLongPress:在屏幕上保持了一段时间
纵向拖拽:
- onVerticalDragStart:指针 和屏幕产生接触井可能开始纵向移动;
- onVerticalDragUpdate:指针和屏幕产生接触,在纵向上发生移动并保持移动
- onVerticalDragEnd:指针和屏幕产生接触结束;
横线拖拽:
- onHorizontalDragStart:指针和屏幕产生接触并可能开始横向移动;
- ontlorizontalDragUpdate:指针和屏幕产生接触,在横向上发生移动井保持移动:
- onHorizontalDragEnd:指针和屏幕产生接触结東:
移动:
- onPanstart:指针和屏幕产生接触井可能开始横向移动或者纵向移动。如果设置了onHorizontal0ragstart 或者 onverticaloragstart,该回调方法会引发崩溃;
- onPanUpdate:指针和屏幕产生接触,在横向或者纵向上发生移动井保持移动。如果设置 了 onHorizontal0ragupdate 或者 onvertical0ragupdate,该回调方法会引发崩溃。
- onPanEnd:指针先前和屏幕产生了接触,并且以特定速度移动,此后不再在屏幕接触上发 生移动。如果设置了 onHorlzontalDragEnd 或者 onvert1calDragEnd,该回调方法会引 发崩溃。
从Widgel的层面来监听手势,我们需要使用:GestureDetector
- 当然,我们也可以使用RaisedButton、FlatButton、InkWell等来监听手势
- globalPosition用于获取相对于屏幕的位置信息
- localPosition用于获取相对于当前Widget的位置信息
GestureDetector(
onTapDown: (details){
print("手指按下:${details.globalPosition}");
},
onTapUp: (details){
print("手指抬起:${details.localPosition}");
},
onTapCancel: (){
print("手势取消:");
},
onTap: (){
print("手势点击:");
},
onDoubleTap: (){
print("手指双击");
},
onLongPress: (){
print("手指长按");
},
child: Container(
width: 200,
height: 200,
color: Colors.green,
)
)
手势冒泡
Center(
child:GestureDetector(
onTapDown: ((details) {
print("outer click");
}),
child:Container(
width: 200,
height: 200,
color: Colors.yellow,
alignment: Alignment.center,
child: GestureDetector(
onTapDown: (details){
print("inner click");
},
child: Container(width: 100,
height: 100,
color: Colors.purple,),
),
)
),
)
嵌套的Container会偶尔出现冒泡的现象,解决方案:不要出现嵌套关系而选择Stack
Stack(
alignment: Alignment.center,
children: [
GestureDetector(
onTapDown: ((details) {
print("outer click");
}),
child:Container(
width: 200,
height: 200,
color: Colors.yellow,
alignment: Alignment.center,
)
),
IgnorePointer(//忽略手势点击
child: GestureDetector(
onTapDown: (details){
print("inner click");
},
child: Container(width: 100,
height: 100,
color: Colors.purple,),
),
)
],
),
组件间事件传递
使用 event_bus: ^2.0.0
// 1.创建全局的EventBus对象
final eventBus = EventBus();
//2.发出事件
eventBus.fire("你好啊,李银河!");
// 3.监听事件的类型
eventBus.on<String>().listen((event) {
setState(() {
print(event);
_message = event;
});
});