Listener介绍
Listener
它是次要的性能是用来监听屏幕触摸事件,取决于它的子组件区域范畴,比方按下、挪动、抬起、勾销等操作时能够增加监听。
咱们晓得Flutter
组件只有按钮才会有事件,那么如果我须要在文字或者某个容器上增加事件那我就须要借助Listener
视频教程地址
手势系列视频教程地址
在什么状况下应用Listener?
Listener
罕用于当手指滑动屏幕时进行暗藏键盘或者下拉刷新、上拉加载时进行事件监听。
个别在理论的开发过程中咱们很少会用到Listener
来监听手势,个别都是通过GestureDetector
来进行监听或者应用MouseRegion
来监听鼠标的事件,而MouseRegion
罕用于web开发中,GestureDetector
罕用于app。
Listener原理
- 当指针按下时,Flutter会对应用程序执行命中测试(Hit Test),以确定指针与屏幕接触的地位存在哪些组件(widget)
- 指针按下事件(以及该指针的后续事件)而后被散发到由命中测试发现的最外部的组件
- 事件会沿着最外部的组件向组件树的根冒泡散发
- 没有机制勾销或进行“冒泡”过程
Listener构造函数
咱们常常应用的回调函数次要有三个
- onPointerDown()
- onPointerMove()
- onpointUp()
const Listener({ Key key, this.onPointerDown, this.onPointerMove, // We have to ignore the lint rule here in order to use deprecated // parameters and keep backward compatibility. // TODO(tongmu): After it goes stable, remove these 3 parameters from Listener // and Listener should no longer need an intermediate class _PointerListener. // https://github.com/flutter/flutter/issues/36085 @Deprecated( 'Use MouseRegion.onEnter instead. See MouseRegion.opaque for behavioral difference. ' 'This feature was deprecated after v1.10.14.' ) this.onPointerEnter, @Deprecated( 'Use MouseRegion.onExit instead. See MouseRegion.opaque for behavioral difference. ' 'This feature was deprecated after v1.10.14.' ) this.onPointerExit, @Deprecated( 'Use MouseRegion.onHover instead. See MouseRegion.opaque for behavioral difference. ' 'This feature was deprecated after v1.10.14.' ) this.onPointerHover, this.onPointerUp, this.onPointerCancel, this.onPointerSignal, this.behavior = HitTestBehavior.deferToChild, Widget child, }) : assert(behavior != null), _child = child, super(key: key);
Listener属性和阐明
字段 | 属性 | 形容 |
---|---|---|
onPointerDown | PointerDownEventListener | 指针按下时触发回调 |
onPointerMove | PointerMoveEventListener | 指针挪动时触发回调 |
onPointerUp | PointerUpEventListener | 指针移开时触发回调 |
onPointerSignal | PointerSignalEventListener | 当指针信号呈现时调用 |
onPointerCancel | PointerCancelEventListener | 指针勾销时触发回调 |
onPointerEnter | PointerEnterEventListener | 当指针进入区域时回调(已废除) |
onPointerExit | PointerExitEventListener | 当指针移出区域时回调(已废除) |
onPointerHover | PointerHoverEventListener | 当没有触发 [onPointerDown] 的指针扭转时调用 |
behavior | HitTestBehavior | 在命中测试期间如何体现 |
child | Widget | 子组件 |
Listener根本应用
咱们这里次要是针对onPointerDown
、onPointerMove
、onPointerUp
进行演示,因为咱们在平时的开发过程中最罕用到的属性就是这三个,而且其余的属性也都被废除掉了。
import 'package:flutter/material.dart';class ListenerExample extends StatefulWidget { @override _ListenerExampleState createState() => _ListenerExampleState();}class _ListenerExampleState extends State<ListenerExample> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Listener"), ), body: Center( child: Stack( children: [ Listener( onPointerDown: (event) { print("onPointerDown----$event"); }, onPointerMove: (event) { print("onPointerMove----$event"); }, onPointerUp: (event) { print("onPointerUp----$event"); }, // onPointerSignal: (event) { // print("onPointerSignal----$event"); // }, // onPointerCancel: (event) { // print("onPointerCancel----$event"); // }, // onPointerEnter: (event) { // print("onPointerEnter----$event"); // }, // onPointerExit: (event) { // print("onPointerExit----$event"); // }, // onPointerHover: (event) { // print("onPointerHover----$event"); // }, child: Container( color: Colors.pink, child: Text("Jimi", style: TextStyle( color: Colors.white, fontSize: 30 ), ), ), ), Positioned( child: Listener( onPointerDown: (event) { print("red---- $event"); }, child: Container( width: 100, height: 100, color: Colors.red, child: Text("Jimi"), ), ), ) ], ), ), ); }}
控制台输入
咱们这里先点击橙色容器,在点击一次红色容器,他们打印的后果如下。
flutter: onPointerDown----PointerDownEvent#128be(position: Offset(204.5, 403.5))flutter: onPointerUp----PointerUpEvent#a9558(position: Offset(204.5, 403.5))flutter: red---- PointerDownEvent#8ffdf(position: Offset(140.5, 317.0))
PointerEvent介绍
PointerEvent
是触摸、手写笔、鼠标事件的基类。
在上文中,咱们晓得了什么是Listener
并写了一个简略的案例,在应用案例的过程中咱们的事件外面都带了一个event
参数,而所有的事件最终都是继承自PointerEvent
,那咱们接下来看看event
的参数有什么作用。
PointerEvent构造函数
const PointerEvent({ this.embedderId = 0, this.timeStamp = Duration.zero, this.pointer = 0, this.kind = PointerDeviceKind.touch, this.device = 0, this.position = Offset.zero, Offset? localPosition, this.delta = Offset.zero, Offset? localDelta, this.buttons = 0, this.down = false, this.obscured = false, this.pressure = 1.0, this.pressureMin = 1.0, this.pressureMax = 1.0, this.distance = 0.0, this.distanceMax = 0.0, this.size = 0.0, this.radiusMajor = 0.0, this.radiusMinor = 0.0, this.radiusMin = 0.0, this.radiusMax = 0.0, this.orientation = 0.0, this.tilt = 0.0, this.platformData = 0, this.synthesized = false, this.transform, this.original,}) : localPosition = localPosition ?? position, localDelta = localDelta ?? delta;
PointerEvent属性和阐明
PointerEvent
的属性十分多,但在咱们理论的开发过程中很少会应用到,只有在特定的情景下才会应用对应的属性。
如须要做一个全局悬浮的按钮咱们会应用到position
如须要做绘图软件咱们须要用到buttons
、kind
等
所以大家能够依据理论的利用场景来应用对应的属性即可,上面是我对PointerEvent
的属性进行的一个详细描述。
总共29个属性
字段 | 属性 | 形容 |
---|---|---|
embedderId | int | 标识平台事件ID |
timeStamp | Duration | 事件调度工夫 |
pointer | int | 指针惟一标识符,每一次点击都会是一个新的,不会反复 |
kind | PointerDeviceKind | 指针事件的输出设施类型 |
device | int | 设施惟一标识符,在交互中会重复使用 |
position | Offset | 指针绝对于全局坐标的偏移 |
localPosition | Offset | 指针绝对于以后容器坐标的偏移 |
delta | Offset | 两次指针挪动事件的间隔 |
localDelta | Offset | 两次指针挪动事件的间隔(以后容器) |
buttons | int | 它是*button常量,常常与kind配合应用,做绘图的画笔软件是常常用到该属性,如果它的值为6,kind是PointerDeviceKind.invertedStylus,那么这示意一个倒置触控笔 |
down | bool | 设置以后指针是否按下 |
obscured | bool | 是否遮挡应用程序的窗口,该属性官网还没实现 |
pressure | double | 按压力度,压力传感器(如iPhone的3D Touch)中应用,取值0.0-1.0 |
pressureMin | double | 按压力度最小值 |
pressureMax | double | 按压力度最大值 |
distance | double | 检测物体与输出外表的间隔 |
distanceMin | double | 限度检测物体与输出外表的间隔最小值 |
distanceMax | double | 限度检测物体与输出外表的间隔最大值 |
size | double | 被按下屏幕的区域大小 |
radiusMajor | double | 接触椭圆沿主轴的半径,以逻辑像素为单位 |
radiusMinor | double | 接触椭圆沿短轴的半径,以逻辑像素为单位 |
radiusMin | double | radiusMajor和radiusMinor报告的最小值 |
radiusMax | double | radiusMajor和radiusMinor报告的最大值 |
orientation | double | 检测到的物体的方向(指针挪动方向),以弧度为单位 |
tilt | double | 检测到的物体的歪斜角度,以弧度为单位 |
platformData | int | 与事件关联的不通明平台特定数据 |
synthesized | bool | 设置事件是否由 Flutter 合成。 |
transform | Matrix4 | 用于从全局坐标转换此事件的转换 |
original | PointerEvent | 在任何transform之前的原始未转换PointerEvent事件 |
behavior属性
behavior
属性,它决定子组件如何响应命中测试,它的值类型为HitTestBehavior
,这是一个枚举类,有三个枚举值
HitTestBehavior.deferToChild
对子组件一个接一个的进行命中测试,如果子组件中有测试通过的,则以后组件通过,这就意味着,如果指针事件作用于子组件上时,其父级组件也必定能够收到该事件。
HitTestBehavior.opaque
在命中测试时,将以后组件当成不通明解决(即便自身是通明的),最终的成果相当于以后Widget的整个区域都是点击区域
HitTestBehavior.translucent
点击组件通明区域时,能够对本身边界内及底部可视区域都进行命中测试,这意味着点击顶部组件通明区域时,顶部组件和底部组件都能够接管到事件
代码演示
import 'package:flutter/material.dart';class ListenerSimpleExample extends StatefulWidget { @override _ListenerSimpleExampleState createState() => _ListenerSimpleExampleState();}class _ListenerSimpleExampleState extends State<ListenerSimpleExample> with AutomaticKeepAliveClientMixin { @override bool get wantKeepAlive => true; @override Widget build(BuildContext context) { super.build(context); return Scaffold( appBar: AppBar( title: Text("Listener"), ), body: Center( child: Stack( children: [ Listener( child: ConstrainedBox( constraints: BoxConstraints.tight(Size(400, 200)), child: Container( color: Colors.greenAccent, ) ), onPointerDown: (event) => print("绿色盒子被点击了"), ), Listener( child: ConstrainedBox( constraints: BoxConstraints.tight(Size(400, 200)), child: Center(child: Text("点击文字", style: TextStyle( color: Colors.white, fontSize: 30 ),)), ), onPointerDown: (event) => print("文字点击事件回调"), behavior: HitTestBehavior.deferToChild, // behavior: HitTestBehavior.opaque, // behavior: HitTestBehavior.translucent, ) ], ), ), ); }}
当属性设置为HitTestBehavior.deferToChild控制台输入后果
咱们这里演示每次都是先点击绿色盒子在点击文字,以便大家能更好的分辨出这三个属性的应用区别
flutter: 绿色盒子被点击了flutter: 文字点击事件回调
当属性设置为HitTestBehavior.opaque控制台输入后果
flutter: 文字点击事件回调flutter: 文字点击事件回调
当属性设置为HitTestBehavior.translucent控制台输入后果
flutter: 文字点击事件回调flutter: 绿色盒子被点击了flutter: 文字点击事件回调
总结
Listener
是Flutter
中比拟重要的功能性组件,它次要的性能是用来监听屏幕触摸事件,事件回调能够获取对应的属性来个性化定制app性能。