Flutter - 手势

Pointers

在移动端,各个平台或UI系统的原始指针事件模型基本都是一致,即:一次完整的事件分为三个阶段:手指按下、手指移动、和手指抬起,而更高级别的手势(如点击、双击、拖动等)都是基于这些原始事件的。

当指针按下时,Flutter会对应用程序执行命中测试(Hit Test),以确定指针与屏幕接触的位置存在哪些widget, 指针按下事件(以及该指针的后续事件)然后被分发到由命中测试发现的最内部的widget,然后从那里开始,事件会在widget树中向上冒泡,这些事件会从最内部的widget被分发到widget根的路径上的所有Widget,这和Web开发中浏览器的事件冒泡机制相似, 但是Flutter中没有机制取消或停止冒泡过程,而浏览器的冒泡是可以停止的。

Flutter中可以使用Listener widget来监听原始触摸事件,它也是一个功能性widget。

GestureDetector

GestureDetector是一个用于手势识别的功能性Widget,我们通过它可以来识别各种手势,它是指针事件的语义化封装

  • Tap
    • onTapDown指针已经在特定位置与屏幕接触
    • onTapUp指针停止在特定位置与屏幕接触
    • onTaptap事件触发
    • onTapCancel先前指针触发的onTapDown不会在触发tap事件
  • Double tap
    • onDoubleTap用户快速连续两次在同一位置轻敲屏幕.
  • Long press
    • onLongPress指针在相同位置长时间保持与屏幕接触
  • Vertical drag
    • onVerticalDragStart指针已经与屏幕接触并可能开始垂直移动
    • onVerticalDragUpdate指针与屏幕接触并已沿垂直方向移动.
    • onVerticalDragEnd先前与屏幕接触并垂直移动的指针不再与屏幕接触,并且在停止接触屏幕时以特定速度移动
  • Horizontal drag
    • onHorizontalDragStart指针已经接触到屏幕并可能开始水平移动
    • onHorizontalDragUpdate指针与屏幕接触并已沿水平方向移动
    • onHorizontalDragEnd先前与屏幕接触并水平移动的指针不再与屏幕接触,并在停止接触屏幕时以特定速度移动
  • Scale
    • onScaleStart
    • onScaleUpdate
    • onScaleEnd

当同时监听onTap和onDoubleTap事件时,当用户触发tap事件时,会有200毫秒左右的延时,这是因为当用户点击完之后很可能会再次点击以触发双击事件,所以GestureDetector会等一段时间来确定是否为双击事件。如果用户只监听了onTap(没有监听onDoubleTap)事件时,则没有延时。