Flutter EventBus事件总线的应用详解
在Flutter开发中,我们经常会遇到需要进行多个页面之间的通信,即跨页面通信。为了满足这种需求,可以使用Flutter事件总线(EventBus)的方式实现。本文将详细介绍Flutter EventBus事件总线的应用方法,包含以下内容:
- EventBus的基本使用方法
- 如何在Flutter中使用EventBus
- 两个示例,讲解具体如何使用EventBus进行跨页面通信
EventBus的基本使用方法
EventBus是一个Pub/Sub(发布/订阅)事件总线库,它可以用于不同模块之间的通信,并提供了一种简单高效的方式来实现跨页面通信。在使用EventBus之前,我们需要做如下准备:
- 引入EventBus库
dependencies:
event_bus: ^1.1.1
- 创建EventBus对象
我们可以在需要使用EventBus的地方创建一个全局的EventBus对象,以供整个应用使用。
EventBus eventBus = new EventBus();
- 创建Event类
我们需要定义事件类,通常是一个简单的数据类(例如一个字符串类型的事件)。
class MyEvent {
final String message;
MyEvent(this.message);
}
- 发布/订阅事件
在需要发送事件的地方,我们可以使用EventBus对象的fire方法来发送事件:
eventBus.fire(new MyEvent('Hello World!'));
而在需要接收事件的地方,我们可以使用EventBus对象的on方法注册监听器:
eventBus.on<MyEvent>().listen((event) {
print(event.message);
});
这样,当一个MyEvent类型的事件被触发时,监听器会自动被调用,执行我们之前注册的回调函数。
如何在Flutter中使用EventBus
在Flutter中使用EventBus也非常简单,可以参照如下步骤:
- 引入EventBus库
在pubspec.yaml文件中增加依赖:
dependencies:
flutter:
sdk: flutter
event_bus: ^1.1.1
- 在需要使用的页面中创建EventBus对象
我们可以在StatefulWidget的State中创建一个EventBus对象:
class _MyWidgetState extends State<MyWidget> {
EventBus eventBus = new EventBus();
...
}
- 发布/订阅事件
在需要发送事件的地方,我们可以使用EventBus对象的fire方法来发送事件:
eventBus.fire(new MyEvent('Hello World!'));
而在需要接收事件的地方,我们可以使用EventBus对象的on方法注册监听器:
eventBus.on<MyEvent>().listen((event) {
print(event.message);
});
示例一:改变页面颜色
下面我们来看一个具体示例。假设我们有两个页面,分别为HomePage和DetailPage,我们需要实现如下功能:
- 当用户在HomePage中点击一个按钮时,跳转到DetailPage页面
- 在DetailPage页面中,用户可以选择颜色,并返回HomePage页面时,HomePage页面的背景色会变成所选颜色
我们可以使用EventBus来实现这个功能。具体步骤如下:
- 准备工作
我们需要在pubspec.yaml文件中增加依赖,以引入EventBus库。
dependencies:
flutter:
sdk: flutter
event_bus: ^1.1.1
- 创建EventBus对象
在HomePage中,我们需要创建一个EventBus对象:
class _HomePageState extends State<HomePage> {
EventBus eventBus = new EventBus();
...
}
- 定义事件类
我们需要定义一个事件类,用来向HomePage发送颜色改变的事件:
class ColorChangeEvent {
final Color color;
ColorChangeEvent(this.color);
}
- 发布事件
在HomePage中,当用户点击按钮时,我们需要发布一个颜色改变事件:
eventBus.fire(new ColorChangeEvent(Colors.red));
- 执行事件
在HomePage中,我们需要注册一个事件监听器,用来监听颜色改变事件,并根据事件中指定的颜色改变背景色:
eventBus.on<ColorChangeEvent>().listen((event) {
setState(() {
backgroundColor = event.color; // 更新背景色
});
});
而在DetailPage中,当用户选择颜色并返回HomePage时,我们需要关闭DetailPage页面,并发布颜色改变事件:
eventBus.fire(new ColorChangeEvent(selectedColor));
Navigator.of(context).pop();
下面是完整的示例代码:
import 'package:event_bus/event_bus.dart';
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Color backgroundColor = Colors.white;
EventBus eventBus = new EventBus();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('HomePage'),
),
backgroundColor: backgroundColor,
body: Center(
child: RaisedButton(
child: Text('Change Color'),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (_) => DetailPage(eventBus: eventBus)),
);
},
),
),
);
}
@override
void initState() {
super.initState();
eventBus.on<ColorChangeEvent>().listen((event) {
setState(() {
backgroundColor = event.color;
});
});
}
}
class DetailPage extends StatefulWidget {
final EventBus eventBus;
DetailPage({this.eventBus});
@override
_DetailPageState createState() => _DetailPageState();
}
class _DetailPageState extends State<DetailPage> {
Color selectedColor = Colors.red;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('DetailPage'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircleColor(
color: selectedColor,
onColorChoose: (color) => selectedColor = color,
),
RaisedButton(
child: Text('Ok'),
onPressed: () {
widget.eventBus.fire(new ColorChangeEvent(selectedColor));
Navigator.of(context).pop();
},
)
],
),
),
);
}
}
class ColorChangeEvent {
final Color color;
ColorChangeEvent(this.color);
}
class CircleColor extends StatelessWidget {
final Color color;
final Function onColorChoose;
CircleColor({this.color, this.onColorChoose});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () async {
final Color selectedColor = await showDialog(
context: context,
builder: (_) {
return AlertDialog(
title: Text('Choose a color'),
content: SingleChildScrollView(
child: BlockPicker(
pickerColor: color,
onColorChanged: onColorChoose,
),
),
actions: [
FlatButton(
child: Text('Cancel'),
onPressed: () => Navigator.of(context).pop(),
),
FlatButton(
child: Text('Ok'),
onPressed: () => Navigator.of(context).pop(color),
),
],
);
},
);
if (selectedColor != null) {
onColorChoose(selectedColor);
}
},
child: Container(
width: 100,
height: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: color,
),
),
);
}
}
示例二:导航栏颜色同步
我们可以使用EventBus来实现导航栏颜色同步的功能,即在不同页面之间切换时,导航栏背景色自动改变。
具体步骤如下,我们可以参考下面的示例代码:
- 准备工作
我们需要在pubspec.yaml文件中增加依赖,以引入EventBus库。
dependencies:
flutter:
sdk: flutter
event_bus: ^1.1.1
- 创建EventBus对象
在MyApp中,我们需要创建一个EventBus对象:
class MyApp extends StatelessWidget {
EventBus eventBus = new EventBus();
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(eventBus: eventBus),
);
}
}
- 定义事件类
我们需要定义一个事件类,用来向所有页面发送导航栏颜色改变的事件:
class ThemeDataChangeEvent {
final Color primaryColor;
ThemeDataChangeEvent(this.primaryColor);
}
- 发布事件
在HomePage中,我们需要发布一个导航栏颜色改变事件:
eventBus.fire(new ThemeDataChangeEvent(Colors.red));
- 执行事件
在所有页面中,我们需要注册一个事件监听器,用来监听导航栏颜色改变事件,并根据事件中指定的颜色改变导航栏背景色:
eventBus.on<ThemeDataChangeEvent>().listen((event) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: event.primaryColor,
));
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
primaryColor: event.primaryColor, // 改变主题颜色
),
home: HomePage(eventBus: eventBus),
);
});
完整示例代码如下:
import 'package:event_bus/event_bus.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class MyApp extends StatelessWidget {
EventBus eventBus = new EventBus();
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(eventBus: eventBus),
);
}
}
class HomePage extends StatelessWidget {
final EventBus eventBus;
HomePage({this.eventBus});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('HomePage'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.color_lens),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (_) => DetailPage(eventBus: eventBus)),
);
},
)
],
),
body: Center(),
);
}
}
class DetailPage extends StatefulWidget {
final EventBus eventBus;
DetailPage({this.eventBus});
@override
_DetailPageState createState() => _DetailPageState();
}
class _DetailPageState extends State<DetailPage> {
Color selectedColor = Colors.red;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('DetailPage'),
),
body: Center(
child: CircleColor(
color: selectedColor,
onColorChoose: (color) => selectedColor = color,
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.color_lens),
onPressed: () {
widget.eventBus.fire(new ThemeDataChangeEvent(selectedColor));
Navigator.of(context).pop();
},
),
);
}
}
class CircleColor extends StatelessWidget {
final Color color;
final Function onColorChoose;
CircleColor({this.color, this.onColorChoose});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () async {
final Color selectedColor = await showDialog(
context: context,
builder: (_) {
return AlertDialog(
title: Text('Choose a color'),
content: SingleChildScrollView(
child: BlockPicker(
pickerColor: color,
onColorChanged: onColorChoose,
),
),
actions: [
FlatButton(
child: Text('Cancel'),
onPressed: () => Navigator.of(context).pop(),
),
FlatButton(
child: Text('Ok'),
onPressed: () => Navigator.of(context).pop(color),
),
],
);
},
);
if (selectedColor != null) {
onColorChoose(selectedColor);
}
},
child: Container(
width: 100,
height: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: color,
),
),
);
}
}
class ThemeDataChangeEvent {
final Color primaryColor;
ThemeDataChangeEvent(this.primaryColor);
}
void main() {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: Colors.blue,
));
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
final eventBus = EventBus();
runApp(MyApp(
eventBus: eventBus,
));
eventBus.on<ThemeDataChangeEvent>().listen((event) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: event.primaryColor,
));
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
primaryColor: event.primaryColor, // 改变主题颜色
),
home: HomePage(eventBus: eventBus),
);
});
}
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Flutter EventBus事件总线的应用详解 - Python技术站