Flutter 触摸事件监听 Listener 手势识别示例

Posted 龙衣

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter 触摸事件监听 Listener 手势识别示例相关的知识,希望对你有一定的参考价值。

欢迎新关注的朋友,在这里主要分享微信小程序、Flutter、android、NodeJS相关的文章,说牛批点就是全栈技术(手动狗头)。

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,// 子布局 })

示例

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

Flutter 触摸事件监听 Listener 、手势识别示例示例伪代码如下:

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 = 0, // 与事件关联的特定于平台的不透明数据。 this.synthesized = false, // 设置事件是否由Flutter合成。 this.transform, // 用于将该事件从全局坐标转换为事件接收者的坐标空间的转换。 this.original, // 应用任何 transform 之前的原始未转换的 PointerEvent  })

手势识别 GestureDetector

检测手势的widget。被GestureDetector包裹的widget,可以很方便的监听到手势相关操作。如:单击、双击、长按等。

查看构造函数支持的属性:

GestureDetector({ Key key, this.child, this.onTapDown,// 点击按下时 this.onTapUp,// 点击抬起时 this.onTap,// 点击 this.onTapCancel,// 点击取消 this.onSecondaryTapDown, this.onSecondaryTapUp, this.onSecondaryTapCancel, this.onDoubleTap,// 双击 this.onLongPress,// 长按 this.onLongPressStart,// 长按开始 this.onLongPressMoveUpdate,// 长按移动更新 this.onLongPressUp,// 长按抬起 this.onLongPressEnd,// 长按结束 this.onVerticalDragDown,// 垂直移动回调,不能与 onScale,onPan,同时使用 this.onVerticalDragStart, this.onVerticalDragUpdate, this.onVerticalDragEnd, this.onVerticalDragCancel,  this.onHorizontalDragDown,// 水平移动回调,不能与 onScale,onPan,同时使用 this.onHorizontalDragStart, this.onHorizontalDragUpdate, this.onHorizontalDragEnd, this.onHorizontalDragCancel, this.onForcePressStart,// 按压力开始 this.onForcePressPeak,// 按压力顶峰 this.onForcePressUpdate, this.onForcePressEnd, this.onPanDown,// 移动按下,不能与 onScale,onVerticalDrag,onHorizontalDrag,同时使用 this.onPanStart,// 移动开始 this.onPanUpdate, this.onPanEnd, this.onPanCancel, this.onScaleStart,// 缩放开始,不能与 onPan ,onVerticalDrag,onHorizontalDrag,同时使用 this.onScaleUpdate, this.onScaleEnd, this.behavior,// 此手势检测器在命中测试期间应如何表现。HitTestBehavior 枚举值:deferToChild,opaque,translucent this.excludeFromSemantics = false,// 是否从语义树中排除这些手势。 this.dragStartBehavior = DragStartBehavior.start,// 确定处理拖动开始行为的方式。枚举值:down,start })

需要注意的是:

1.onScale,onVerticalDrag,onHorizontalDrag 三个参数不能同时使用,2.onScale ,onPan不能同时使用3.onPan,onVerticalDrag,onHorizontalDrag 三个参数不能同时使用

否则会提示:Incorrect GestureDetector arguments. 参数冲突。

示例效果:Flutter 触摸事件监听 Listener 、手势识别示例

点击、双击、长按、水平滑动、垂直滑动

在蓝色区域内点击、双击、长按、水平滑动、垂直滑动在控制台可以看到回调信息输出。

Flutter 触摸事件监听 Listener 、手势识别示例

跟随手指移动效果

Flutter 触摸事件监听 Listener 、手势识别示例实现思路就是在onPan回调里面处理widget的位置。Flutter 触摸事件监听 Listener 、手势识别示例

缩放效果

Flutter 触摸事件监听 Listener 、手势识别示例实现思路就是在onScale回调里面处理widget宽高Flutter 触摸事件监听 Listener 、手势识别示例

手势识别基类 GestureRecognizer

所有手势识别器都继承的基类。查看GestureDetector源码发现,GestureDetector的相关手势识别也是继承自该类。

例如双击回调监听使用到了DoubleTapGestureRecognizerFlutter 触摸事件监听 Listener 、手势识别示例

在之前的文章 Flutter 文本 Text 参数图文理解[1] 中使用了TextSpan来拼接文本,并在特定的文本区域实现点击事件。

由于GestureDetector包裹的child必须是widget,而TextSpan并不是widget所以这里不能使用GestureDetector,但是TextSpan中提供了更为基础的手势识别类GestureRecognizer,通过该类我们可以实现手势监听。

使用实例

Flutter 触摸事件监听 Listener 、手势识别示例伪代码实现如下:Flutter 触摸事件监听 Listener 、手势识别示例

自定义手势识别

当有多个手势时,可能会产生冲突。如对图片进行点击、长按、缩放等操作的时候,如何识别用户当前是点击还是长按,缩放。如果想要精确地处理复杂交互手势,可自定义手势识别器来处理冲突问题。

如下示例:分别给红蓝背景的框框设置点击事件,但是点击蓝色背景时,底部的红色框框没有点击事件没有被识别。Flutter 触摸事件监听 Listener 、手势识别示例上面的示例中想要红色框框也能识别手势事件,该怎么实现呢?

上面我们也介绍了指针的基本事件Listener,将第一个GestureDetector改为Listener组件,再来看一下效果:可以看到使用Listener组件能够优先识别到触摸事件。但是想实现最外层的onTap事件,使用原始指针Listener组件来实现会比较复杂。

这时候可以使用自定义一个手势识别器来实现。参考:Flutter核心技术与实战[2]

end~

References

[1] Flutter 文本 Text 参数图文理解: https://longyi.blog.csdn.net/article/details/104830878
[2] Flutter核心技术与实战: https://time.geekbang.org/column/article/116326


看到这的可以三连(在看、评论、转发)走起了~


以上是关于Flutter 触摸事件监听 Listener 手势识别示例的主要内容,如果未能解决你的问题,请参考以下文章

flutter 中监听滑动事件

Flutter了解之手势

Flutter 实现手写签名效果

flutter组件总结

flutter学习-事件监听

android 怎么样让按钮自动执行点击事件