flutter 手势监听、事件总线
本文最后更新于:2022年4月22日 上午
手势监听、事件总线
Listener
可以监听简单的事件 按下、移动,然后释放或取消,如果要监听更高级的事件可以用 MouseRegion
或 GestureDetector
该方式监听的事件会冒泡 (没有机制取消或停止“冒泡”过程),一般用来监听滑动,下拉刷新,上拉加载等事件的监听
- onPointerDown 按下事件
- onPointerMove 移动事件
- onPointerUp 点击事件
- onPointerHover 悬浮事件
- onPointerCancel 取消事件
- onPointerSignal
class TestListener extends StatelessWidget {
const TestListener({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Listener(
onPointerUp: (event) {
// Offset(192.3, 451.6) 能够获取到距离屏幕左边的距离
print('父点击$event');
},
child: Container(
color: Colors.red,
width: 300,
height: 300,
alignment: Alignment.center, // 会套一个 Align
// 如果直接嵌套 Container 时,内部的 Container 会占满父的宽高,需要用一个容器进行隔离
child: Listener(
onPointerUp: (event) {
print('子点击${event.position}');
},
child: Container(width: 200, height: 200, color: Colors.green),
),
),
);
}
}
GestureDetector
GestureDetector
有更多丰富的事件,例如双击,长按等事件
默认不会冒泡,如果出现冒泡,可以通过 套Stack
或者给子元素套IgnorePointer
来组织冒泡
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('手势监听')),
body: Center(
child: GestureDetector(
onTap: () {
print('父点击');
},
child: Container(
color: Colors.red,
width: 300,
height: 300,
alignment: Alignment.center, // 会套一个 Align
// 如果直接嵌套 Container 时,内部的 Container 会占满父的宽高,需要用一个容器进行隔离
child: GestureDetector(
onTap: () {
print('子点击');
},
onLongPress: () {
print('长按');
},
child: Container(width: 200, height: 200, color: Colors.green),
),
),
),
),
);
}
}
bus 总线
和 vue
,react
中的事件总线概念一致,使用第三方库 event_bus进行实现,该库的源代码及其简洁
1. 创建全局bus总线
import 'package:event_bus/event_bus.dart';
// 创建全局事件总线,抽离到单独的文件中
final eventBus = EventBus();
2. 创建事件类型
// 事件类型
class UserChnageEvent {
String username;
int age;
UserChnageEvent(this.username, this.age);
}
3. 监听事件
eventBus.on<UserChnageEvent>().listen()
的方式来进行监听
class Child1 extends StatefulWidget {
const Child1({Key? key}) : super(key: key);
@override
State<Child1> createState() => _Child1State();
}
class _Child1State extends State<Child1> {
@override
void initState() {
super.initState();
eventBus.on<UserChnageEvent>().listen((event) {
print('child1 监听: ${event.username}');
});
}
@override
Widget build(BuildContext context) {
return Container(child: Text('child1'));
}
}
4. 发射事件
eventBus.fire(xxx)
的方式进行发射事件,且将参数传入进去
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('bus 总线')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Child1(),
Child2(),
],
),
),
floatingActionButton: FloatingActionButton(
child: Text('发出事件'),
onPressed: () {
eventBus.fire(UserChnageEvent('lfm', 20));
},
),
);
}
}
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议,转载请注明出处。