Flutter-事件监听

190 阅读1分钟

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,
            ),
          )
      ),

image-20221025144922722

手势识别 Gesture

Gesture分层非常多的种类:

点击:

  1. onTapDown:用户发生手指按下的操作
  2. onTapup:用户发生手指抬起的操作
  3. onTap:用户点击事件完成
  4. 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,
              )
          )

image-20221025151904983

手势冒泡
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,),
            ),
            )
          ),
      )

image-20221025152741840

嵌套的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,),
                ),
              )
            ],
          ),

image-20221025154413368

组件间事件传递

使用 event_bus: ^2.0.0

// 1.创建全局的EventBus对象
final eventBus = EventBus();
//2.发出事件
eventBus.fire("你好啊,李银河!");
// 3.监听事件的类型
eventBus.on<String>().listen((event) {
  setState(() {
    print(event);
    _message = event;
  });
});