如需转载,请注明出处:Flutter学习笔记(33)--GestureDetector手势识别

这篇随笔主要记录的学习内容是GestureDetector手势识别,内容包括识别单击、双击、长按、组件拖拽和缩放处理。

  • 单击、双击、长按

先看下demo,很简单,GestureDetector本身也是一个组件,GestureDetector识别其内部子组件的手势动作,GestureDetector的构造方法内给我们提供了onTap单击、onDoubleTap双击、onLongPress长按的是回调方法。

识别到用户的手势操作后会执行对应的回调方法,demo的处理就是简单的更新一下text的文案。

  1. import 'package:flutter/material.dart';
  2.  
  3. class GestureDetectorDemo extends StatefulWidget {
  4. @override
  5. State<StatefulWidget> createState() {
  6. return _GestureDetectorDemo();
  7. }
  8. }
  9.  
  10. class _GestureDetectorDemo extends State {
  11. String _operation = "No Gesture detected!"; //保存事件名
  12. @override
  13. Widget build(BuildContext context) {
  14. return MaterialApp(
  15. title: 'GestureDetectorDemo',
  16. home: new Scaffold(
  17. appBar: AppBar(
  18. title: Text('GestureDetectorDemo'),
  19. leading: Icon(Icons.arrow_back),
  20. ),
  21. body: new GestureDetector(
  22. child: Container(
  23. alignment: Alignment.center,
  24. color: Colors.red,
  25. width: ,
  26. height: ,
  27. child: Text(
  28. _operation,
  29. style: TextStyle(color: Colors.teal),
  30. ),
  31. ),
  32. onTap: () => setState(() => _operation = 'onTap'),//单机回调
  33. onDoubleTap: () => setState(() => _operation = 'onDoubleTap'),//双击回调
  34. onLongPress: () => setState(() => _operation = 'onLongPress'),//长按回调
  35. ),
  36. ),
  37. );
  38. }
  39. }

注:这里要说明一下,如果同时监听的onTap和onDoubleTap这两个事件的话,onTap会有200ms的延时,因为因为用户在点击一次之后很有可能会再点击一次来触发双击的事件,所以GestureDetector会等一段时间来确定用户是不是要双击,如果只是监听了onTap而没有监听onDoubleTap的话,就不会有延时了。

  • 组件拖动

老样子先看demo再讲解:

  1. import 'package:flutter/material.dart';
  2.  
  3. class GestureDragDemo extends StatefulWidget {
  4. @override
  5. State<StatefulWidget> createState() {
  6. return _GestureDragDemoState();
  7. }
  8. }
  9.  
  10. class _GestureDragDemoState extends State<GestureDragDemo> {
  11. double _top = 0.0; //距离顶部的偏移量
  12. double _left = 0.0; //距离底部的偏移量
  13. @override
  14. Widget build(BuildContext context) {
  15. return MaterialApp(
  16. title: 'GestureDragDemo',
  17. home: Scaffold(
  18. appBar: AppBar(
  19. title: Text('GestureDragDemo'),
  20. leading: Icon(Icons.keyboard_backspace),
  21. ),
  22. body: Stack(
  23. children: <Widget>[
  24. Positioned(
  25. top: _top,
  26. left: _left,
  27. child: GestureDetector(
  28. child: CircleAvatar(
  29. backgroundColor: Colors.red,
  30. child: Text(
  31. 'A',
  32. style: TextStyle(color: Colors.white),
  33. ),
  34. ),
  35. onPanDown: (DragDownDetails downDetails) {
  36. //手指按下时会执行此回调
  37. // print('手指按下的位置:$downDetails.globalPosition');
  38. },
  39. onPanUpdate: (DragUpdateDetails dragUpdateDetails) {
  40. //手指滑动时会执行次回调
  41. setState(() {
  42. //手指滑动时会多次触发onPanUpdate回调,更新偏移量并重新绘制
  43. //dragUpdateDetails.delta.dx获取y轴方向的偏移量
  44. _top += dragUpdateDetails.delta.dy;
  45. //dragUpdateDetails.delta.dy获取x轴方向的偏移量
  46. _left += dragUpdateDetails.delta.dx;
  47. });
  48. },
  49. onPanEnd: (DragEndDetails dragEndDetails) {
  50. //打印滑动结束时在x、y轴上的速度
  51. // print(dragEndDetails.velocity);
  52. },
  53. ),
  54. ),
  55. ],
  56. )),
  57. );
  58. }
  59. }
  • DragDownDetails.globalPosition:当用户按下时,此属性为用户按下的位置相对于屏幕(而非父组件)原点(左上角)的偏移。
  • DragUpdateDetails.delta:当用户在屏幕上滑动时,会触发多次Update事件,delta指一次Update事件的滑动的偏移量。
  • DragEndDetails.velocity:该属性代表用户抬起手指时的滑动速度(包含x、y两个轴的),示例中并没有处理手指抬起时的速度,常见的效果是根据用户抬起手指时的速度做一个减速动画。

也很简单,我们主要看下onPanUpdate这个回调方法,在我们手指滑动的过程中,会多次执行这个回调,在回调中我们处理下x、y方向的偏移量让后重新绘制就ok了。

偏移量打印:

  • 单一方向拖动

上面的拖动是可以往任意方向拖动的,在日常的开发中,有可能会遇到只允许水平(拼图验证)或竖直方向上进行拖动,DestureDetector也为我们提供了对应的响应事件:

看下demo示例:

  1. import 'package:flutter/material.dart';
  2.  
  3. class GestureDragDemo extends StatefulWidget {
  4. @override
  5. State<StatefulWidget> createState() {
  6. return _GestureDragDemoState();
  7. }
  8. }
  9.  
  10. class _GestureDragDemoState extends State<GestureDragDemo> {
  11. double _top = 0.0; //距离顶部的偏移量
  12. double _left = 0.0; //距离底部的偏移量
  13. @override
  14. Widget build(BuildContext context) {
  15. return MaterialApp(
  16. title: 'GestureDragDemo',
  17. home: Scaffold(
  18. appBar: AppBar(
  19. title: Text('GestureDragDemo'),
  20. leading: Icon(Icons.keyboard_backspace),
  21. ),
  22. body: Stack(
  23. children: <Widget>[
  24. Positioned(
  25. top: _top,
  26. left: _left,
  27. child: GestureDetector(
  28. child: CircleAvatar(
  29. backgroundColor: Colors.red,
  30. child: Text(
  31. 'A',
  32. style: TextStyle(color: Colors.white),
  33. ),
  34. ),
  35. onPanDown: (DragDownDetails downDetails) {
  36. //手指按下时会执行此回调
  37. // print('手指按下的位置:$downDetails.globalPosition');
  38. },
  39. // onPanUpdate: (DragUpdateDetails dragUpdateDetails) {
  40. // //手指滑动时会执行次回调
  41. // setState(() {
  42. // //手指滑动时会多次触发onPanUpdate回调,更新偏移量并重新绘制
  43. // //dragUpdateDetails.delta.dx获取y轴方向的偏移量
  44. // _top += dragUpdateDetails.delta.dy;
  45. // print('Y:$dragUpdateDetails.delta.dy');
  46. // //dragUpdateDetails.delta.dy获取x轴方向的偏移量
  47. // _left += dragUpdateDetails.delta.dx;
  48. // print('X:$dragUpdateDetails.delta.dx');
  49. // });
  50. // },
  51. onHorizontalDragUpdate: (DragUpdateDetails dragUpdateDetails){
  52. setState(() {
  53. _left += dragUpdateDetails.delta.dx;
  54. });
  55. },
  56. onPanEnd: (DragEndDetails dragEndDetails) {
  57. //打印滑动结束时在x、y轴上的速度
  58. // print(dragEndDetails.velocity);
  59. },
  60. ),
  61. ),
  62. ],
  63. )),
  64. );
  65. }
  66. }
  • 缩放
  1. import 'package:flutter/material.dart';
  2.  
  3. class GestureScaleDemo extends StatefulWidget{
  4. @override
  5. State<StatefulWidget> createState() {
  6. return _GestureScaleDemoState();
  7. }
  8. }
  9.  
  10. class _GestureScaleDemoState extends State {
  11. double _width = 200.0;
  12. @override
  13. Widget build(BuildContext context) {
  14. return MaterialApp(
  15. title: 'GestureScaleDemo',
  16. home: Scaffold(
  17. appBar: AppBar(
  18. title: Text('GestureScaleDemo'),
  19. ),
  20. body: Center(
  21. child: GestureDetector(
  22. child: Image.asset('images/banner.png',width: _width),
  23. onScaleUpdate: (ScaleUpdateDetails scaleUpdateDetails){
  24. setState(() {
  25. //缩放倍数在0.8到10倍之间
  26. _width=*scaleUpdateDetails.scale.clamp(., 10.0);
  27. });
  28. },
  29. ),
  30. ),
  31. ),
  32. );
  33. }
  34. }

Flutter学习笔记(33)--GestureDetector手势识别的更多相关文章

  1. Flutter学习笔记(36)--常用内置动画

    如需转载,请注明出处:Flutter学习笔记(36)--常用内置动画 Flutter给我们提供了很多而且很好用的内置动画,这些动画仅仅需要简单的几行代码就可以实现一些不错的效果,Flutter的动画分 ...

  2. Flutter学习笔记(41)--自定义Dialog实现版本更新弹窗

    如需转载,请注明出处:Flutter学习笔记(41)--自定义Dialog实现版本更新弹窗 功能点: 1.更新弹窗UI 2.强更与非强更且别控制 3.屏蔽物理返回键(因为强更的时候点击返回键,弹窗会消 ...

  3. Flutter学习笔记(3)--Dart变量与基本数据类型

    一.变量 在Dart里面,变量的声明使用var.Object或Dynamic关键字,如下所示: var name = ‘张三’: 在Dart语言里一切皆为对象,所以如果没有将变量初始化,那么它的默认值 ...

  4. Flutter学习笔记(4)--Dart函数

    如需转载,请注明出处:Flutter学习笔记(4)--Dart函数 Dart是一个面向对象的语言,所以函数也是对象,函数属于Function对象,函数可以像参数一样传递给其他函数,这样便于做回调处理: ...

  5. Flutter学习笔记(5)--Dart运算符

    如需转载,请注明出处:Flutter学习笔记(5)--Dart运算符 先给出一个Dart运算符表,接下来在逐个解释和使用.如下:                            描述       ...

  6. Flutter学习笔记(6)--Dart异常处理

    如需转载,请注明出处:Flutter学习笔记(6)--Dart异常处理 异常是表示发生了意外的错误,如果没有捕获异常,引发异常的隔离程序将被挂起,并且程序将被终止: Dart代码可以抛出并捕获异常,但 ...

  7. Flutter学习笔记(8)--Dart面向对象

    如需转载,请注明出处:Flutter学习笔记(7)--Dart异常处理 Dart作为高级语言,支持面向对象的很多特性,并且支持基于mixin的继承方式,基于mixin的继承方式是指:一个类可以继承自多 ...

  8. Flutter学习笔记(9)--组件Widget

    如需转载,请注明出处:Flutter学习笔记(9)--组件Widget 在Flutter中,所有的显示都是Widget,Widget是一切的基础,我们可以通过修改数据,再用setState设置数据(调 ...

  9. Flutter学习笔记(10)--容器组件、图片组件

    如需转载,请注明出处:Flutter学习笔记(10)--容器组件.图片组件 上一篇Flutter学习笔记(9)--组件Widget我们说到了在Flutter中一个非常重要的理念"一切皆为组件 ...

随机推荐

  1. C#中的any和all

    any是判断列表里面是否有哪怕一个: all是判断列表里面是否每一项都包含:

  2. SpringBoot外部化配置使用Plus版

    本文如有任何纰漏.错误,请不吝指正! PS: 之前写过一篇关于SpringBoo中使用配置文件的一些姿势,不过嘛,有句话(我)说的好:曾见小桥流水,未睹观音坐莲!所以再写一篇增强版,以便记录. 序言 ...

  3. SD.Team主题形象小人偶

              W e ♥ S D     ♫ ♪ 咔咔咔~可能源码冲突会造成小人偶光头 :)

  4. ReentrantLock解析及源码分析

    本文结构 Tips:说明一部分概念及阅读源码需要的基础内容 ReentrantLock简介 公平机制:对于公平机制和非公平机制进行介绍,包含对比 实现:Sync源码解析额,公平和非公平模式的加锁.解锁 ...

  5. MANIFEST.MF是个什么?

    MANIFEST.MF是个什么? 写这篇文件主要记录JRA文件里面到底是什么?然后MANIFEST.MF又是什么?Springboot 如何只有Main方法就可以运行的? Springboot项目打包 ...

  6. 在线编写复杂的数学公式--EdrawMath

    网址: EdrawMath , 非常好用

  7. EntityFramework数据持久化 Linq介绍

    一.LINQ概述与查询语法 二.LINQ方法语法基础(重点) 三.LINQ聚合操作与元素操作(重点) 四.数据类型转换(重点) 一.LINQ概述与查询语法 1.LINQ(Language Integr ...

  8. ASP.NET中使用Entity Framework开发登陆注册Demo

    这里更多的是当作随身笔记使用,记录一下学到的知识,以便淡忘的时候能快速回顾 当前步骤是该项目的第一部分 第一部分(当前) 第二部分 大完结版本 直接上步骤,有类似的开发登陆注册也可以参考. 登陆注册的 ...

  9. Java实现 LeetCode 622 设计循环队列(暴力大法)

    622. 设计循环队列 设计你的循环队列实现. 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环.它也被称为"环形缓冲器" ...

  10. Java实现 LeetCode 416 分割等和子集

    416. 分割等和子集 给定一个只包含正整数的非空数组.是否可以将这个数组分割成两个子集,使得两个子集的元素和相等. 注意: 每个数组中的元素不会超过 100 数组的大小不会超过 200 示例 1: ...