java 手势识别_Flutter学习笔记(33)--GestureDetector手势识别

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

单击、双击、长按

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

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

import 'package:flutter/material.dart';classGestureDetectorDemo extends StatefulWidget {

@override

StatecreateState() {return_GestureDetectorDemo();

}

}class_GestureDetectorDemo extends State {

String _operation= "No Gesture detected!"; //保存事件名

@override

Widget build(BuildContext context) {returnMaterialApp(

title:'GestureDetectorDemo',

home:newScaffold(

appBar: AppBar(

title: Text('GestureDetectorDemo'),

leading: Icon(Icons.arrow_back),

),

body:newGestureDetector(

child: Container(

alignment: Alignment.center,

color: Colors.red,

width:300,

height:200,

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';classGestureDragDemo extends StatefulWidget {

@override

StatecreateState() {return_GestureDragDemoState();

}

}class _GestureDragDemoState extends State{double _top = 0.0; //距离顶部的偏移量

double _left = 0.0; //距离底部的偏移量

@override

Widget build(BuildContext context) {returnMaterialApp(

title:'GestureDragDemo',

home: Scaffold(

appBar: AppBar(

title: Text('GestureDragDemo'),

leading: Icon(Icons.keyboard_backspace),

),

body: Stack(

children:[

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了。

偏移量打印:

975e9010454d1fa95a161675224e4b3e.png

单一方向拖动

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

9a9045b3ec39167ad3f6dbbdc96e6397.png

看下demo示例:

import 'package:flutter/material.dart';classGestureDragDemo extends StatefulWidget {

@override

StatecreateState() {return_GestureDragDemoState();

}

}class _GestureDragDemoState extends State{double _top = 0.0; //距离顶部的偏移量

double _left = 0.0; //距离底部的偏移量

@override

Widget build(BuildContext context) {returnMaterialApp(

title:'GestureDragDemo',

home: Scaffold(

appBar: AppBar(

title: Text('GestureDragDemo'),

leading: Icon(Icons.keyboard_backspace),

),

body: Stack(

children:[

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';classGestureScaleDemo extends StatefulWidget{

@override

StatecreateState() {return_GestureScaleDemoState();

}

}class_GestureScaleDemoState extends State {double _width = 200.0;

@override

Widget build(BuildContext context) {returnMaterialApp(

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=200*scaleUpdateDetails.scale.clamp(.8, 10.0);

});

},

),

),

),

);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值