【Flutter点滴知识|Flutter 触摸事件监听 Listener 、手势识别示例

文章目录
触摸监听 Listener
示例
手势识别 GestureDetector
点击、双击、长按、水平滑动、垂直滑动
跟随手指移动效果
缩放效果
手势识别基类 GestureRecognizer
使用实例
自定义手势识别
在Android开发中,完整的触摸事件会经历:手指按下(ACTION_DOWN)、手指移动(ACTION_MOVE)、和手指抬起(ACTION_UP),三个阶段,在Flutter中提供Listener组件来实现类似的功能。Android还提供了GestureDetector来帮助我们识别一些基本的触摸手势,如类似于:单击、双击、长按等操作,在Flutter中也提供了手势识别组件GestureDetector来实现类似的功能。
触摸监听 Listener
响应常见指针事件而调用回调的 widget。
查看构造函数支持的属性:
const Listener({
Key key,
this.onPointerDown,// 按下手指回调
this.onPointerMove,// 移动手指回调
this.onPointerUp,// 抬起手指回调
this.onPointerCancel,// 取消回调
this.onPointerSignal,// 该对象在触摸发生时回调
this.behavior = HitTestBehavior.deferToChild,// 命中测试期间的行为方式
Widget child,// 子布局
})

示例
居中显示的一个区域,触摸区域输出对应的坐标

示例伪代码如下:
Listener(
child: Container(
alignment: Alignment.center,
color: Colors.blue,
width: 300.0,
height: 300.0,
),
onPointerDown: (PointerDownEvent event){
print("onPointerDown:${event.position.toString()}");
},
onPointerMove: (PointerMoveEvent event){
print("onPointerMove:${event.position.toString()}");
},
onPointerUp: (PointerUpEvent event){
print("onPointerUp:${event.position.toString()}");
},
onPointerSignal: (PointerSignalEvent event){
print("onPointerSignal:${event.position.toString()}");
},
onPointerCancel: (PointerCancelEvent event){
print("onPointerCancel:${event.position.toString()}");
},
),

当触发指针事件时,参数PointerDownEvent、PointerMoveEvent、PointerUpEvent中的event会记录下触摸相关的信息。
这些信息来自PointerEvent,查看其构造函数中字段信息:
const PointerEvent({
this.timeStamp = Duration.zero, // 事件调度的时间
this.pointer = 0, // 指针的唯一标识符,不能重用
this.kind = PointerDeviceKind.touch, //为其生成事件的输入设备的类型:touch(触摸设备),mouse(鼠标),stylus(手写笔),invertedStylus(手写笔),unknown(未知设备)
this.device = 0, // 指示设备的唯一标识符,可在各种交互中重复使用
this.position = Offset.zero, // 指针位置的坐标
Offset localPosition, // 指针位置的本地坐标
this.delta = Offset.zero, // 自上一个 PointerMoveEvent 或 PointerHoverEvent 后,指针移动的逻辑像素距离。
Offset localDelta, // 事件接收者的本地坐标
this.buttons = 0, // 使用 Button 常量的位字段
this.down = false, // 设置指针当前是否向下。
this.obscured = false,
this.pressure = 1.0, // 按压力度
this.pressureMin = 1.0, // 按压力度最小值,该数字始终小于或等于1.0。
this.pressureMax = 1.0, // 按压力度最大值,它将始终大于或等于1.0。
this.distance = 0.0, // 被检测物体与输入表面的距离
this.distanceMax = 0.0, // 如果此输入设备无法检测到“悬停触摸”输入事件,则为0.0。
this.size = 0.0, // 屏幕被按下的区域。
this.radiusMajor = 0.0, // 沿椭圆的接触椭圆的半径
this.radiusMinor = 0.0, // 沿椭圆的接触椭圆的半径
this.radiusMin = 0.0, // 可以为此指针报告 radiusMajor 和 radiusMinor 的最小值
this.radiusMax = 0.0, // 可以为此指针报告 radiusMajor 和 radiusMinor 的最大值
this.orientation = 0.0, // 指针移动方向,是一个角度值
this.tilt = 0.0, // 被检测物体的倾斜角度
this.platformData = https://www.it610.com/article/0, // 与事件关联的特定于平台的不透明数据。
this.synthesized = false, // 设置事件是否由Flutter合成。
this.transform, // 用于将该事件从全局坐标转换为事件接收者的坐标空间的转换。
this.original, // 应用任何 transform 之前的原始未转换的 PointerEvent
})

需要注意的是:
onScale,onVerticalDrag,onHorizontalDrag 三个参数不能同时使用,
onScale ,onPan不能同时使用
onPan,onVerticalDrag,onHorizontalDrag 三个参数不能同时使用
否则会提示:Incorrect GestureDetector arguments. 参数冲突。
示例效果:

点击、双击、长按、水平滑动、垂直滑动
在蓝色区域内点击、双击、长按、水平滑动、垂直滑动在控制台可以看到回调信息输出。
跟随手指移动效果
【【Flutter点滴知识|Flutter 触摸事件监听 Listener 、手势识别示例】实现思路就是在onPan回调里面处理widget的位置。

缩放效果
实现思路就是在onScale回调里面处理widget的宽高。

手势识别基类 GestureRecognizer
所有手势识别器都继承的基类。查看GestureDetector源码发现,GestureDetector的相关手势识别也是继承自该类。
例如双击回调监听使用到了DoubleTapGestureRecognizer:

在之前的文章 Flutter 文本 Text 参数图文理解 中使用了TextSpan来拼接文本,并在特定的文本区域实现点击事件。
由于GestureDetector包裹的child必须是widget,而TextSpan并不是widget所以这里不能使用GestureDetector,但是TextSpan中提供了更为继承的手势识别类GestureRecognizer,通过该类我们可以实现手势监听。
使用实例
伪代码实现如下:

自定义手势识别
当有多个手势时,可能会产生冲突。如对图片进行点击、长按、缩放等操作的时候,如何识别用户当前是点击还是长按,缩放。如果想要精确地处理复杂交互手势,可自定义手势识别器来处理冲突问题。
如下示例:分别给红蓝背景的框框设置点击事件,但是点击蓝色背景时,底部的红色框框没有点击事件没有被识别。
上面的示例中想要红色框框也能识别手势事件,该怎么实现呢?
上面我们也介绍了指针的基本事件Listener,将第一个GestureDetector改为Listener组件,再来看一下效果:
可以看到使用Listener组件能够优先识别到触摸事件。但是想实现最外层的onTap事件,使用原始指针Listener组件来实现会比较复杂。
这时候可以使用自定义一个手势识别器来实现。
参考:Flutter核心技术与实战

wan~
————————————————
版权声明:本文为CSDN博主「_龙衣」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ITxiaodong/article/details/105083031

    推荐阅读