美文网首页
Gesture手势检测和滑动冲突

Gesture手势检测和滑动冲突

作者: icecreamco | 来源:发表于2019-07-19 20:36 被阅读0次

    最近flutter稳定版本由1.5升级到了1.7,GestureDetector手势检测类也得到了完善,新增了很多事件回调方法。接下来主要介绍下GestureDetector基本使用、注意事项、1.5到1.7升级引起的问题和滑动冲突。

    GestureDetector简介

    • GestureDetector接受child参数,检测child上手势操作的回调

    • downcancel

      GestureRecognizer之间相互竞争,down事件可能会有多个手势生出并接收回调,当某一个事件流程正式胜出,其他GestureRecognizer会调用其cancel方法

      // down
      onTapDown;
      onVerticalDragDown;
      onHorizontalDragDown;
      onPanDown;
      // cancel
      onTapCancel;
      onVerticalDragCancel;
      onHorizontalDragCancel;
      onPanCancel;
      
    • tap单击

      事件回调顺序onTapDown -> onTapUp -> onTap

      • onTap: 单击回调
      • onTapUp: 单击手势抬起回调
    • longPress长按

      事件回调顺序onLongPressStart -> onLongPress -> onLongPressMoveUpdate -> onLongPressEnd -> onLongPressUp

      • onLongPressStart:长按开始
      • onLongPress:长按回调
      • onLongPressMoveUpdate:长按移动
      • onLongPressEnd:长按事件结束
      • onLongPressUp:长按手势抬起
    • onDoubleTap双击回调

    • drag水平/垂直拖拽

      事件回调顺序onXXDragStart -> onXXDragUpdate -> onXXDragEnd

      • onXXDragStart:拖拽开始
      • onXXDragUpdate:拖拽过程移动
      • onXXDragEnd:拖拽结束
    • scale缩放

      事件回调顺序onScaleStart -> onScaleUpdate -> onScaleEnd

      • onScaleStart:缩放开始

      • onScaleUpdate:缩放更新

      • onScaleEnd:缩放结束

    • pan拖拽

      事件回调顺序onPanStart -> onPanUpdate -> onPanEnd

      • onPanStart:拖拽开始
      • onPanUpdate:拖拽过程移动
      • onPanEnd:拖拽结束

    Listener简介

    如果需要处理原始用户手势事件,可以使用Listner,其提供了原始手指操作的回调,核心方法有onPointerDownonPointerMoveonPointerUp,每一个事件流都是按照onPointerDown -> onPointerMove -> onPointerUp的顺序进行的,可以继承至Listner定制自定义手势检测。

    • onPointerDown:手指按下屏幕
    • onPointerMove:手指滑动
    • onPointerUp:手指离开屏幕

    GestureDetector手势事件冲突

    • scalepan事件冲突,不能同时存在,建议直接使用scaleScaleUpdateDetails参数中,如果scale == 1则可以认为进入pan流程,前后两个focalPoint的差值即是DragUpdateDetails中的delta
    • HorizontalDragVerticalDrag不能共存,且如果存在scale的话,Drag事件优先级比较高,scale事件将被忽略。如果既要检测横向拖拽又要检测纵向拖拽,有两种方案:
      • GestureDetector嵌套,分别提供vertivalDraghorizontalDrag的回调,优势是简单方便,劣势是不能检测任意方向上的滑动
      • pan事件处理,直接处理pan事件流,可以检测到任意方向上的拖拽,有点是比较灵活和全面,缺点是稍显复杂

    升级1.7遇到的问题和解决方案

    1.5及1.5以前的版本可以嵌套GestureDetector同时检测scalepan,嵌套内层的GestureDetector优先处理事件流,如果内层嵌套不处理,则外层嵌套处理事件流,非常方便。

    1.7上scale事件完全成为pan事件流的超集,不能共存,且不能嵌套,需要在scale相关回调中自行判断是滑动、缩放还是转动事件,通常,在不考虑转动事件下,认为若scale == 1为拖拽事件流,否则为缩放事件流,再进行相应操作。

    滑动冲突的解决方案

    典型场景,TabBarView结合内部可以滑动的view,例如大图页面ScalableImageWidget,会产生典型的滑动冲突。

    解决方案是内部ScalableImageWidget优先级较高,决定是否处理滑动事件,若不处理,则移交给外部TabBarView处理。具体如下:

    1. root页面持有TabBarView和其child ScalableImageWidget构造方法,设置标志位_needHandleScroll决定TabBarViewphysics属性取PageScrollPhysics还是NeverScrollableScrollPhysics,设置ScalableImageWidget回调scrollStateCallback
    2. ScalableImageWidget根据边界条件决定是否消费滑动事件,若不消费,则调用ScrollStateCallback回调设置root页面_needHandleScroll标志位,将处理权交给TabBarView
    3. TabBarView获取了滑动事件处理权,则监听滑动动画的执行,滑动动画结束后将处理权移交给内部child

    相关文章

      网友评论

          本文标题:Gesture手势检测和滑动冲突

          本文链接:https://www.haomeiwen.com/subject/wlhelctx.html