关于flutter:Flutter-手势系列教程Listener

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根本应用

咱们这里次要是针对onPointerDownonPointerMoveonPointerUp 进行演示,因为咱们在平时的开发过程中最罕用到的属性就是这三个,而且其余的属性也都被废除掉了。

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

如须要做绘图软件咱们须要用到buttonskind

所以大家能够依据理论的利用场景来应用对应的属性即可,上面是我对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: 文字点击事件回调

总结

ListenerFlutter中比拟重要的功能性组件,它次要的性能是用来监听屏幕触摸事件,事件回调能够获取对应的属性来个性化定制app性能。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理