Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

Flutter进阶—点击、拖动和其他手势

$
0
0

Flutter中的手势系统有两个层次。第一层具有原始指针事件,其描述了穿过屏幕的指针(例如触摸、鼠标和触控笔)的位置和移动。第二层具有手势,其描述由一个或多个指针移动组成的语义动作。

指针

指针代表用户与设备屏幕交互的原始数据。有四种类型的指针事件:

  • PointerDownEvent:指针已经在特定位置联系了屏幕。
  • PointerMoveEvent:指针已经从屏幕上的一个位置移动到另一个位置。
  • PointerUpEvent:指针已停止接触屏幕。
  • PointerCancelEvent:此指针的输入不再针对此应用程序。

在指针落下,框架在您的应用程序寻找处理触摸事件的视图,以确定指针与触摸屏接触的位置处存在哪些控件。然后将指针落下事件(以及该指针的后续事件)分派到处理触摸事件的视图的最内层控件。在那里,事件会弹起控件树,并被分派到从最内层控件到树根的路径上的所有小部件。没有取消或停止指针事件进一步调度的机制。

要直接从控件层监听指针事件,可以使用Listener控件。但是,一般来说,最好使用手势(下面会介绍原因)。

手势

手势表示从多个指针事件中识别的语义动作(例如点击、拖动和缩放),甚至可能有多个指针。手势可以调度多个事件,对应于手势的生命周期(例如拖动开始、拖动更新和拖动结束):

点击

  • onTapDown:可能导致点击的指针已联系到屏幕的特定位置。
  • onTapUp:触发点按的指针已停止在特定位置与屏幕联系。
  • onTap:发生了点击。
  • onTapCancel:以前触发onTapDown的指针最终没有导致点击。

双击

  • onTapDown:onDoubleTap:用户已经快速连续地在同一位置点击屏幕两次。

长按

  • onLongPress:指针在相同的位置与屏幕保持的长时间接触。

垂直拖动

  • onVerticalDragStart:指针已经接触到屏幕,而且可能开始垂直移动。
  • onVerticalDragUpdate:与屏幕接触并垂直移动的指针沿垂直方向移动。
  • onVerticalDragEnd:以前与屏幕接触并垂直移动的指针不再与屏幕接触,并且当其停止接触屏幕时以特定速度移动。

水平拖动

  • onHorizontalDragStart:指针已经接触到屏幕,而且可能开始水平移动。
  • onHorizontalDragUpdate:与屏幕接触并水平移动的指针沿水平方向移动。
  • onHorizontalDragEnd:以前与屏幕接触并水平移动的指针不再与屏幕接触,并且当其停止接触屏幕时以特定速度移动。

要从控件层监听手势,可以使用GestureDetector控件。

如果使用质感设计控件,则其中许多控件已经响应了点击或手势。例如,IconButton和FlatButton响应点击,ListView响应滑动来触发滚动。如果没有使用这些控件,但是想要“ink splash”的点击效果,您可以使用InkWell控件。

手势消歧

在屏幕上给定的位置,可能有多个手势检测器。所有这些手势检测器在流过指针事件流时都会监听,并尝试识别特定的手势。GestureDetector控件基于哪个回调非空,决定尝试识别哪些手势。

当屏幕上给定指针有多个手势识别器时,框架通过使每个识别器加手势竞技场来决定用户打算使用哪个手势。手势竞技场使用以下规则决定哪个手势赢:

  • 在任何时候,识别器可以宣布失败并离开竞技场。如果竞技场中只剩下一个识别器,则该识别器是获胜者。
  • 在任何时候,识别器可以宣布胜利,这导致其获胜,所有剩余的识别器都会失败。

例如,当消除水平和垂直拖动的歧义时,当他们收到指针落下事件时,两个识别器进入竞技场。识别器观察指针移动事件。如果用户水平移动指针超过一定数量的逻辑像素,水平识别器将声明胜利,手势将被解释为水平拖动。类似地,如果用户垂直移动超过一定数量的逻辑像素,则垂直识别器将声明胜利。

当只有水平(或垂直)拖动识别器时,手势竞技场是有益的。在这种情况下,竞技场只有一个识别器,水平拖动将被立即识别,这意味着水平移动的第一个像素可以被视为拖动,用户不需要等待进一步的手势消歧。

作者:hekaiyou 发表于2017/5/15 11:45:40 原文链接
阅读:310 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>