【flutter】flutter原始指针事件PointerEvent处理

本文详细介绍了Flutter中的原始指针事件处理,包括事件的三个阶段、Listener widget的使用以及PointerEvent的行为设置。重点讨论了behavior参数对命中测试的影响,如何设置使整个Widget区域成为点击区域,并探讨了如何通过IgnorePointer和AbsorbPointer控制子树对PointerEvent的响应。

(1)在移动端,各个平台或UI系统的原始指针事件模型基本都是一致,即:一次完整的事件分为三个阶段:手指按下、手指移动、和手指抬起,而更高级别的手势(如点击、双击、拖动等)都是基于这些原始事件的。
当指针按下时,Flutter会对应用程序执行命中测试(Hit Test),以确定指针与屏幕接触的位置存在哪些widget。注意,只有通过命中测试的Widget才能触发事件。
(2)Flutter中可以使用Listener widget来监听原始触摸事件,它也是一个功能性widget。

Listener({
  Key key,
  this.onPointerDown, //手指按下回调
  this.onPointerMove, //手指移动回调
  this.onPointerUp,//手指抬起回调
  this.onPointerCancel,//触摸事件取消回调
  this.behavior = HitTestBehavior.deferToChild, //在命中测试期间如何表现
  Widget child
})

(3)说说Listener behavior:

Widget getBody() {
  return Container(
    child: Listener(
        child: ConstrainedBox(
          constraints: BoxConstraints.tight(Size(double.infinity, double.infinity)),
          child: Center(child: Text("Box A")),
        ),
        //behavior: HitTestBehavior.opaque,
        onPointerDown: (event) => print("down A")
    ),
  );
}

说明:
(a)注释掉上面behavior时,只有点击Text("Box A")时,才会打印down A;点击Text之外区域不会打印down A。
(b)当将behavior设置为opaque时,点击Text之外区域也会打印down A。
(c)opaque是不透明、模糊的意思。
(d)在命中测试的时候,将behavior设置为opaque,相当于当前Widget的整个区域都是点击区域。不然会按照deferToChild去子widget判断是否命中测试,而该例中子widget就是 Text("Box A") 。
(e)若将behavior设置为deferToChild时,子widget会一个接一个的进行命中测试,如果子Widget中有测试通过的,则当前Widget通过,这就意味着,如果指针事件作用于子Widget上时,其父(祖先)Widget也肯定可以收到该事件。
(4)忽略PointerEvent
假如我们不想让某个子树响应PointerEvent的话,我们可以使用IgnorePointer和AbsorbPointer,这两个Widget都能阻止子树接收指针事件,不同之处在于AbsorbPointer本身会参与命中测试,而IgnorePointer本身不会参与,这就意味着AbsorbPointer本身是可以接收指针事件的(但其子树不行),而IgnorePointer不可以。

Widget getBody() {
  return Container(
    child: Listener(
      child: AbsorbPointer(
        child: Listener(
          child: Container(
            color: Colors.green,
          ),
          onPointerDown: (event)=>print("in"),
        ),
      ),
      onPointerDown: (event)=>print("up"),
    ),
  );
}

说明:
(a)上面代码点击只会输出up。这是因为AbsorbPointer自己会进行命中测试,而子widget会被阻止。
(b)将AbsorbPointer改为IgnorePointer时,则什么都不会输出。
(c)将AbsorbPointer改为Container时,则先输出in,后输出up。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值