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

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

  • 单击、双击、长按

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

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

import 'package:flutter/material.dart';

class GestureDetectorDemo extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _GestureDetectorDemo();
}
} class _GestureDetectorDemo extends State {
String _operation = "No Gesture detected!"; //保存事件名
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'GestureDetectorDemo',
home: new Scaffold(
appBar: AppBar(
title: Text('GestureDetectorDemo'),
leading: Icon(Icons.arrow_back),
),
body: new GestureDetector(
child: Container(
alignment: Alignment.center,
color: Colors.red,
width: ,
height: ,
child: Text(
_operation,
style: TextStyle(color: Colors.teal),
),
),
onTap: () => setState(() => _operation = 'onTap'),//单机回调
onDoubleTap: () => setState(() => _operation = 'onDoubleTap'),//双击回调
onLongPress: () => setState(() => _operation = 'onLongPress'),//长按回调
),
),
);
}
}

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

  • 组件拖动

老样子先看demo再讲解:

import 'package:flutter/material.dart';

class GestureDragDemo extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _GestureDragDemoState();
}
} class _GestureDragDemoState extends State<GestureDragDemo> {
double _top = 0.0; //距离顶部的偏移量
double _left = 0.0; //距离底部的偏移量
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'GestureDragDemo',
home: Scaffold(
appBar: AppBar(
title: Text('GestureDragDemo'),
leading: Icon(Icons.keyboard_backspace),
),
body: Stack(
children: <Widget>[
Positioned(
top: _top,
left: _left,
child: GestureDetector(
child: CircleAvatar(
backgroundColor: Colors.red,
child: Text(
'A',
style: TextStyle(color: Colors.white),
),
),
onPanDown: (DragDownDetails downDetails) {
//手指按下时会执行此回调
// print('手指按下的位置:$downDetails.globalPosition');
},
onPanUpdate: (DragUpdateDetails dragUpdateDetails) {
//手指滑动时会执行次回调
setState(() {
//手指滑动时会多次触发onPanUpdate回调,更新偏移量并重新绘制
//dragUpdateDetails.delta.dx获取y轴方向的偏移量
_top += dragUpdateDetails.delta.dy;
//dragUpdateDetails.delta.dy获取x轴方向的偏移量
_left += dragUpdateDetails.delta.dx;
});
},
onPanEnd: (DragEndDetails dragEndDetails) {
//打印滑动结束时在x、y轴上的速度
// print(dragEndDetails.velocity);
},
),
),
],
)),
);
}
}
  • DragDownDetails.globalPosition:当用户按下时,此属性为用户按下的位置相对于屏幕(而非父组件)原点(左上角)的偏移。
  • DragUpdateDetails.delta:当用户在屏幕上滑动时,会触发多次Update事件,delta指一次Update事件的滑动的偏移量。
  • DragEndDetails.velocity:该属性代表用户抬起手指时的滑动速度(包含x、y两个轴的),示例中并没有处理手指抬起时的速度,常见的效果是根据用户抬起手指时的速度做一个减速动画。

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

偏移量打印:

  • 单一方向拖动

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

看下demo示例:

import 'package:flutter/material.dart';

class GestureDragDemo extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _GestureDragDemoState();
}
} class _GestureDragDemoState extends State<GestureDragDemo> {
double _top = 0.0; //距离顶部的偏移量
double _left = 0.0; //距离底部的偏移量
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'GestureDragDemo',
home: Scaffold(
appBar: AppBar(
title: Text('GestureDragDemo'),
leading: Icon(Icons.keyboard_backspace),
),
body: Stack(
children: <Widget>[
Positioned(
top: _top,
left: _left,
child: GestureDetector(
child: CircleAvatar(
backgroundColor: Colors.red,
child: Text(
'A',
style: TextStyle(color: Colors.white),
),
),
onPanDown: (DragDownDetails downDetails) {
//手指按下时会执行此回调
// print('手指按下的位置:$downDetails.globalPosition');
},
// onPanUpdate: (DragUpdateDetails dragUpdateDetails) {
// //手指滑动时会执行次回调
// setState(() {
// //手指滑动时会多次触发onPanUpdate回调,更新偏移量并重新绘制
// //dragUpdateDetails.delta.dx获取y轴方向的偏移量
// _top += dragUpdateDetails.delta.dy;
// print('Y:$dragUpdateDetails.delta.dy');
// //dragUpdateDetails.delta.dy获取x轴方向的偏移量
// _left += dragUpdateDetails.delta.dx;
// print('X:$dragUpdateDetails.delta.dx');
// });
// },
onHorizontalDragUpdate: (DragUpdateDetails dragUpdateDetails){
setState(() {
_left += dragUpdateDetails.delta.dx;
});
},
onPanEnd: (DragEndDetails dragEndDetails) {
//打印滑动结束时在x、y轴上的速度
// print(dragEndDetails.velocity);
},
),
),
],
)),
);
}
}
  • 缩放
import 'package:flutter/material.dart';

class GestureScaleDemo extends StatefulWidget{
@override
State<StatefulWidget> createState() {
return _GestureScaleDemoState();
}
} class _GestureScaleDemoState extends State {
double _width = 200.0;
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'GestureScaleDemo',
home: Scaffold(
appBar: AppBar(
title: Text('GestureScaleDemo'),
),
body: Center(
child: GestureDetector(
child: Image.asset('images/banner.png',width: _width),
onScaleUpdate: (ScaleUpdateDetails scaleUpdateDetails){
setState(() {
//缩放倍数在0.8到10倍之间
_width=*scaleUpdateDetails.scale.clamp(., 10.0);
});
},
),
),
),
);
}
}

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. NOI2006 最大获利 洛谷P4174

    洛谷题目传送门! 题目描述 新的技术正冲击着手机通讯市场,对于各大运营商来说,这既是机遇,更是挑战.THU 集团旗下的 CS&T 通讯公司在新一代通讯技术血战的前夜,需要做太多的准备工作,仅就 ...

  2. [COCOS2DX-LUA]0-002.在C++中如何接收Lua方法,然后tolua

    用过COCOS2DX-LUA的同学们,大家都知道回调函数这个东西,在Lua中,我们可以把一个方法当成是一个参数传递给另一个方法,然后在方法中进行调用.但是我们经常要写C++代码,然后再转成Lua,那么 ...

  3. [Python基础]008.异常

    异常 异常处理 捕获异常 抛出异常 自定义异常 一些常见的异常 异常处理 捕获异常 try/except 与C,java等语言用try/catch来捕获异常相似,Python使用try/except ...

  4. css 3 背景图片为渐变色(渐变色背景图片) 学习笔记

    6年不研究CSS发现很多现功能都没有用过,例如渐变色,弹性盒子等,年前做过一个简单的管理系统,由于本人美工不好,设计不出好看的背景图片,偶然百度到背景图片可以使用渐变色(感觉发现了新大陆).以后的项目 ...

  5. Chisel3 - model - DefWire, Reg, Memory, Prim

    https://mp.weixin.qq.com/s/KkkqvekWHG6yrqwHUECRIw   介绍如何定义Wire/Reg/Memory/Prim.   1. DefWire   Wire( ...

  6. undefined和nul

  7. Linux(十) —— 使用 rz 和 sz 命令上传与下载

    以CentOS 7 系统为例,一般上传下载都是使用的第三方工具,但是在操作上并不方便,每次都要找到对应的目录才可以执行上传.下载操作,比较麻烦. 而CentOS为例的 Linux 系统可以通过安装 插 ...

  8. Physic Design:Floorplan算法概览

    仅用于学习交流,转载请联系本人. 1 floorplan是什么 floorplan常被翻译成布图规划,是指在芯片级别上对模块进行布局,也就是哪个单元放在什么地方,但是单元内部的具体布局并不关心.该步骤 ...

  9. 第九届蓝桥杯JavaC组决(国)赛真题

    1:年龄问题 s夫人一向很神秘.这会儿有人问起她的年龄,她想了想说: "20年前,我丈夫的年龄刚好是我的2倍,而现在他的年龄刚好是我的1.5倍". 你能算出s夫人现在的年龄吗? 这 ...

  10. Java实现 LeetCode 107 二叉树的层次遍历 II(二)

    107. 二叉树的层次遍历 II 给定一个二叉树,返回其节点值自底向上的层次遍历. (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历) 例如: 给定二叉树 [3,9,20,null,null, ...