Flutter手势组件(1):Listener

这篇文章是关于 Flutter 中 Listener 组件的教程,介绍了其功能、使用场景、原理、构造函数、属性等。Listener 用于监听屏幕触摸事件,常用于隐藏键盘、下拉刷新等,其原理涉及指针事件的分发。还列举了常用回调函数、属性及说明,通过案例和控制台输出进行演示,包括 behavior 属性的不同效果。

一、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 进行演示,因为我们在平时的开发过程中最常用到的属性就是这三个,而且其他的属性也都被废弃掉了。

// ignore_for_file: prefer_const_constructors
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: ListenerExample(),
    );
  }
}

class ListenerExample extends StatefulWidget {
  const ListenerExample({super.key});
  @override
  State<ListenerExample> 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) {
                debugPrint("onPointerDown----$event");
              },
              onPointerMove: (event) {
                debugPrint("onPointerMove----$event");
              },
              onPointerUp: (event) {
                debugPrint("onPointerUp----$event");
              },
              child: Container(
                color: Colors.orange,
                width: 200,
                height: 100,                
                child: Text("Listener",
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 30
                  ),
                ),
              ),
            ),

            // 监听指针按下事件
            Positioned(
              left: 100,
              child: Listener(
                onPointerDown: (event) {
                  debugPrint("red---- $event");
                },
                child: Container(
                  width: 100,
                  height: 100,
                  color: Colors.red,
                  child: Text("Jimi"),
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

我们这里先鼠标按下、移动、松开橙色容器,再点击一次红色容器,他们打印的结果如下:

Flutter_event_A.png


posted @ 2024-11-18 16:17  fengMisaka  阅读(24)  评论(0编辑  收藏  举报