热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Flutter基础之GestureDetector手势(交互模型篇)

声明:本篇文章已授权微信公众号YYGeeker独家发布。博主原创文章,转载请注明出处:小嵩的博客介绍GestureDetector是F

声明:本篇文章已授权微信公众号 YYGeeker 独家发布。
博主原创文章,转载请注明出处:小嵩的博客


介绍

GestureDetector是Flutter的手势检测器,它会尝试识别与之非null的回调相对应的手势。对于宽高的处理,如果此Widget组件具有子控件,那么它的大小调整行为将遵从该子控件。若它没有子控件,那么它宽高将变大以适应父控件。

默认情况下,带有不可见子控件的手势检测器会忽略触摸;可以通过行为控制此逻辑。GestureDetector还监听可访问性事件,并将其映射到callback回调。若要忽略可访问性事件,请将ExcludeFromSemantics设置为true。

Flutter中的手势系统有两个独立的层。第一层为原始指针(pointer)事件,它描述了屏幕上指针(例如,触摸、鼠标和触控笔)的位置和移动。 第二层为手势,描述由一个或多个指针移动组成的语义动作,如拖拽、缩放、双击、长按等。


手势

在flutter中,手势表示可以从多个单独的指针事件(甚至可能是多个单独的指针)识别的语义动作(例如点击,拖拽和缩放)。 完整的一个手势可以分发多个事件,对应于手势的生命周期(例如,拖拽开始,拖拽更新和拖拽结束):


  • 单击

    • onTapDown 指针已经在特定位置与屏幕接触
    • onTapUp 指针停止在特定位置与屏幕接触
    • onTap 单击事件触发
    • onTapCancel 先前指针触发的onTapDown不会在触发单击事件
  • 双击

    • onDoubleTap 用户快速连续两次在同一位置轻敲屏幕.
  • 长按

    • onLongPress 指针在相同位置长时间保持与屏幕接触
  • 垂直拖拽

    • onVerticalDragStart 指针已经与屏幕接触并可能开始垂直移动
    • onVerticalDragUpdate 指针与屏幕接触并已沿垂直方向移动.
    • onVerticalDragEnd 先前与屏幕接触并垂直移动的指针不再与屏幕接触,并且在停止接触屏幕时以特定速度移动
  • 水平拖拽

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

继承关系

Object —> Diagnosticable —> DiagnosticableTree —> Widget —> StatelessWidget —> GestureDetector


构造函数

GestureDetector({Key key, Widget child, GestureTapDownCallback onTapDown, GestureTapUpCallback onTapUp, GestureTapCallback onTap, GestureTapCancelCallback onTapCancel, GestureTapDownCallback onSecondaryTapDown, GestureTapUpCallback onSecondaryTapUp, GestureTapCancelCallback onSecondaryTapCancel, GestureTapCallback onDoubleTap, GestureLongPressCallback onLongPress, GestureLongPressStartCallback onLongPressStart, GestureLongPressMoveUpdateCallback onLongPressMoveUpdate, GestureLongPressUpCallback onLongPressUp, GestureLongPressEndCallback onLongPressEnd, GestureDragDownCallback onVerticalDragDown, GestureDragStartCallback onVerticalDragStart, GestureDragUpdateCallback onVerticalDragUpdate, GestureDragEndCallback onVerticalDragEnd, GestureDragCancelCallback onVerticalDragCancel, GestureDragDownCallback onHorizontalDragDown, GestureDragStartCallback onHorizontalDragStart, GestureDragUpdateCallback onHorizontalDragUpdate, GestureDragEndCallback onHorizontalDragEnd, GestureDragCancelCallback onHorizontalDragCancel, GestureForcePressStartCallback onForcePressStart, GestureForcePressPeakCallback onForcePressPeak, GestureForcePressUpdateCallback onForcePressUpdate, GestureForcePressEndCallback onForcePressEnd, GestureDragDownCallback onPanDown, GestureDragStartCallback onPanStart, GestureDragUpdateCallback onPanUpdate, GestureDragEndCallback onPanEnd, GestureDragCancelCallback onPanCancel, GestureScaleStartCallback onScaleStart, GestureScaleUpdateCallback onScaleUpdate, GestureScaleEndCallback onScaleEnd, HitTestBehavior behavior, bool excludeFromSemantics: false, DragStartBehavior dragStartBehavior: DragStartBehavior.start })


常用属性


  • dragStartBehavior → DragStartBehavior
    确定处理拖拽开始行为的方式

  • excludeFromSemantics → bool 是否从语义树中排除这些手势。

    例如,用于显示工具提示的长按手势被排除,因为工具提示本身直接包含在语义树中,因此具有显示它的手势将导致信息的重复。

  • onDoubleTap → GestureTapCallback 用户已快速连续两次在同一位置使用主按钮轻触屏幕。

  • onForcePressEnd → GestureForcePressEndCallback 指针不再与屏幕接触。

  • onForcePressPeak → GestureForcePressPeakCallback 指针与屏幕接触并以最大力按下。力量至少是 ForcePressGestureRecognizer.peakPressure。

  • onForcePressStart → GestureForcePressStartCallback 指针与屏幕接触,并用足够的力按压以启动压力。力量至少是 ForcePressGestureRecognizer.startPressure。

  • onForcePressUpdate → GestureForcePressUpdateCallback 指针与屏幕接触,之前已经通过了 ForcePressGestureRecognizer.startPressure,并且要么在屏幕的平面上移动,要么用不同的力按压屏幕,要么同时按两个屏幕。

  • onHorizontalDragCancel → GestureDragCancelCallback
    先前触发onHorizontalDragDown的指针未完成触发了取消。

  • onHorizontalDragDown → GestureDragDownCallback
    指针已通过主按钮与屏幕接触,并可能开始水平移动。

  • onHorizontalDragEnd → GestureDragEndCallback
    之前与主屏幕接触并且水平移动的指针不再与屏幕接触,并且当它停止接触屏幕时以特定速度移动。

  • onHorizontalDragStart → GestureDragStartCallback
    指针已通过主按钮与屏幕接触,并开始水平移动。

  • onHorizontalDragUpdate → GestureDragUpdateCallback
    与主按钮接触并且水平移动的指针在水平方向上移动。

  • onLongPress → GestureLongPressCallback
    当识别出具有主按钮的长按手势时调用。

  • onLongPressEnd → GestureLongPressEndCallback
    使用主按钮触发长按的指针已停止接触屏幕。

  • onLongPressMoveUpdate → GestureLongPressMoveUpdateCallback
    使用主按钮长按后,指针已被拖动。

  • onLongPressStart → GestureLongPressStartCallback
    当识别出具有主按钮的长按手势时调用。

  • onLongPressUp → GestureLongPressUpCallback
    使用主按钮触发长按的指针已停止接触屏幕。

  • onPanCancel → GestureDragCancelCallback
    先前触发onPanDown的指针未完成。

  • onPanDown → GestureDragDownCallback
    指针已通过主按钮与屏幕接触,并可能开始移动。

  • onPanEnd → GestureDragEndCallback
    先前通过主按钮与屏幕接触并且移动的指针不再与屏幕接触,并且当它停止接触屏幕时以特定速度移动。

  • onPanStart → GestureDragStartCallback
    触摸点与屏幕接触,并已开始移动。

  • onPanUpdate → GestureDragUpdateCallback
    屏幕上的触摸点位置每次改变时,都会触发该回调。

  • onScaleEnd → GestureScaleEndCallback
    指针不再与屏幕接触。

  • onScaleStart → GestureScaleStartCallback
    与屏幕接触的指针已建立焦点,初始比例为1.0。

  • onScaleUpdate → GestureScaleUpdateCallback
    与屏幕接触的指针表示新的焦点和/或比例。

  • onSecondaryTapCancel → GestureTapCancelCallback
    先前触发onSecondaryTapDown的指针不会最终导致点击。

  • onSecondaryTapDown → GestureTapDownCallback
    可能导致使用辅助按钮敲击的指针已在特定位置与屏幕联系。

  • onSecondaryTapUp → GestureTapUpCallback
    将触发带有辅助按钮的敲击的指针已停止在特定位置接触屏幕。

  • onTap → GestureTapCallback
    带主按钮的点击事件触发源头。

  • onTapCancel → GestureTapCancelCallback
    先前触发onTapDown的指针不会导致点击。

  • onTapDown → GestureTapDownCallback
    可能导致使用主按钮敲击的指针已在特定位置与屏幕联系。

  • onTapUp → GestureTapUpCallback
    将触发带主按钮的敲击的指针已停止在特定位置接触屏幕。

  • onVerticalDragCancel → GestureDragCancelCallback
    先前触发onVerticalDragDown的指针未完成。

  • onVerticalDragDown → GestureDragDownCallback
    指针已通过主按钮与屏幕接触,并可能开始垂直移动。

  • onVerticalDragEnd → GestureDragEndCallback
    先前与主屏幕接触并且垂直移动的指针不再与屏幕接触,并且当它停止接触屏幕时以特定速度移动。

  • onVerticalDragStart → GestureDragStartCallback
    指针已通过主按钮与屏幕接触,并已开始垂直移动。

  • onVerticalDragUpdate → GestureDragUpdateCallback
    与主按钮接触并且垂直移动的指针在垂直方向上移动。


常用方法


  • build(BuildContext context) → Widget
    创建组件。
  • debugFillProperties(DiagnosticPropertiesBuilder 属性) →void
    添加与节点关联的其他属性。
  • createElement() → StatelessElement
    创建StatelessElement以管理此组件在UI树中的位置。

使用示例


1. 单击、双击、长按事件

这里通过一个demo,用GestureDetector对Container组件进行手势识别。在触发相应事件后,Container上显示事件名,为了增大点击区域,将Container设置为200×200,代码如下:

import 'package:flutter/material.dart';class GestureDetectorTestRoute extends StatefulWidget {@override_GestureDetectorTestRouteState createState() =>new _GestureDetectorTestRouteState();
}class _GestureDetectorTestRouteState extends State<GestureDetectorTestRoute> {String _operation &#61; "No Gesture detected!"; &#64;overrideWidget build(BuildContext context) {return Scaffold(key: _scaffoldKey,appBar: AppBar(title: Text("GestureDetectorTest"),),body: Center(child: GestureDetector(child: Container(alignment: Alignment.center,color: Colors.blue,width: 200.0,height: 200.0,child: Text(_operation,style: TextStyle(color: Colors.white,fontSize: 14,decoration: TextDecoration.none),),),onTap: () &#61;> updateText("onTap"), //单击onDoubleTap: () &#61;> updateText("onDoubleTap"), //双击onLongPress: () &#61;> updateText("onLongPress"), //长按),),);}//更新文本void updateText(String text) {setState(() {_operation &#61; text;});//提示showSnackBar(text);}var _scaffoldKey &#61; new GlobalKey<ScaffoldState>();void showSnackBar(String message) {var snackBar &#61; SnackBar(content: Text(message),backgroundColor: Colors.lightGreen,duration: Duration(milliseconds: 400));_scaffoldKey.currentState.showSnackBar(snackBar);}
}

效果图如下&#xff1a;

, width: _width),onScaleUpdate: (ScaleUpdateDetails details) {setState(() {//缩放倍数在0.2到20倍之间_width &#61; 240 * details.scale.clamp(0.5, 20.0);});},),);}
}

效果图如下&#xff1a;
Scale


总结

通过这篇文章&#xff0c;我们了解了flutter 所提供的GestureDetector手势检测器的一些基本概念及能力&#xff0c;它内部封装了诸多API&#xff0c;让我们可以很高效快速开发应用。通过文章的内容讲述&#xff0c;我们知道如何去监听单击/双击/拖拽等事件及处理用户的交互逻辑。当然&#xff0c;触摸交互模型里面不可避免地会出现事件竞争和事件冲突问题&#xff0c;本篇文章由于篇幅问题就没有进行讲解了&#xff0c;下篇文章我们将会侧重讲述flutter中的事件竞争及冲突问题。


推荐阅读
  • 先上图引入插件在pubspec.yaml中引入charts_flutter插件使用的时候版本到0.6.0,插件地址:https:github.comgooglecharts使用插件 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文详细介绍了使用C#实现Word模版打印的方案。包括添加COM引用、新建Word操作类、开启Word进程、加载模版文件等步骤。通过该方案可以实现C#对Word文档的打印功能。 ... [详细]
  • 介绍平常在多线程开发中,总避免不了线程同步。本篇就对net多线程中的锁系统做个简单描述。目录一:lock、Monitor1:基础 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 本文介绍了在CentOS 6.4系统中更新源地址的方法,包括备份现有源文件、下载163源、修改文件名、更新列表和系统,并提供了相应的命令。 ... [详细]
  • GreenDAO快速入门
    前言之前在自己做项目的时候,用到了GreenDAO数据库,其实对于数据库辅助工具库从OrmLite,到litePal再到GreenDAO,总是在不停的切换,但是没有真正去了解他们的 ... [详细]
  • MySQL笔记_MySQL笔记1|数据库17问17答
    本文由编程笔记#小编为大家整理,主要介绍了MySQL笔记1|数据库17问17答相关的知识,希望对你有一定的参考价值。 ... [详细]
author-avatar
手机用户2502861125
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有