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基本使用
我们这里主要是针对onPointerDown
、onPointerMove
、onPointerUp
进行演示,因为我们在平时的开发过程中最常用到的属性就是这三个,而且其他的属性也都被废弃掉了。
// 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"),
),
),
)
],
),
),
);
}
}
我们这里先鼠标按下、移动、松开橙色容器,再点击一次红色容器,他们打印的结果如下: