Flutter是Google(全球顶级互联网科技公司)的生的,后台够硬,毫无疑问Flutter即将或已经成为跨平台开发的主流,Flutter野心很大,不仅冲击着原生开发,而且很有可能会烧到Web前端。作为移动端开发者的你,如果不关注Flutter的话,实在说不过去啦!
在APP中,我们经常会需要一个广播机制,用以跨页面事件通知。比如从第一个页面跳转到第二个页面,用户在第二个页面操作的动作行为要及时反馈到第一个页面中(如刷新页面中的数据)。这种场景,一个事件总线便会非常有用,事件总线通常实现了订阅者模式,订阅者模式包含发布者和订阅者两种角色,可以通过事件总线来触发事件和监听事件,本文介绍如何在Flutter中使用EventBus,实现类似以上的场景。
一、效果图
第一个界面初始化状态
第二个界面使用按钮点击发起一个EventBus事件
第一个界面展示了第二个界面发送的数据(即更新了UI)
2、Flutter中集成EventBus
在pubspec.yaml文件中添加event_bus,当前版本1.1.0:
event_bus: ^1.1.0
2、引入EventBus
import 'package:event_bus/event_bus.dart';
3、创建EventBus实例
EventBus eventBus = new EventBus();
YDCEventBusManage.dart全部代码
import 'package:event_bus/event_bus.dart';
EventBus eventBus = new EventBus();
4、定义event, 任意一个Dart class都可以作为一个event
class EventParam{
String id;
String name;
EventParam(this.id,this.name);
String get getName => this.name;
String get getId=>this.id;
}
4、在第一个页面中注册监听
EventBus是通过Dart Streams来实现的,那么我们可以通过对Dart Stream的控制,来实现对EventBus的控制。
监听eventBus中所有的事件。
eventBus.on().listen()
只监听EventParam。
eventBus.on().listen((EventParam data) =>
show(data.name)
);
第一个页面全部源码
import 'package:flutter/material.dart';
import 'package:ydcflutter_app/common/test/CartModel.dart';
import 'package:ydcflutter_app/common/test/Item.dart';
import 'package:provider/provider.dart';
import 'package:ydcflutter_app/eventbus/YDCEventBusManage.dart';
import 'package:ydcflutter_app/eventbus/EventParam.dart';
import 'package:ydcflutter_app/test/EventBusTestPage2.dart';
import 'dart:async';
class EventBusTestPage extends StatefulWidget {
@override
State createState() => new _EventBusTestPageState();
}
class _EventBusTestPageState extends State {
BuildContext mContext;
StreamSubscription _subscription;
var data="";
@override
void initState() {
// TODO: implement initState
super.initState();
//监听登录事件
_subscription=eventBus.on().listen((EventParam data) =>
show(data.name)
);
_subscription.resume();
}
void show(String val) {
setState(() {
data= val;
});
}
@override
Widget build(BuildContext context) {
return new Scaffold( body:Center(
child: Builder(builder: (context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Builder(builder: (context) {
return Text("EventBus回传的数据: ${data}");
}),
Builder(builder: (context) {
print("RaisedButton build"); //在后面优化部分会用到
return RaisedButton(
child: Text("跳转到第二页面"),
onPressed: () {
//给购物车中添加商品,添加后总价会更新
//Provider.of(context).add(Item(10.0, 1));
Navigator.of(context).push(new MaterialPageRoute(
builder: (BuildContext context) {
return new EventBusTestPage2();
},
));
},
);
}),
],
);
}),
),
);
}
Widget dividerWidget = new Container(
//margin: const EdgeInsets.only( left: 10.0,right: 10.0),
child: new Padding(
padding: const EdgeInsets.only(left: 0.0, right: 0.0),
child:
new Divider(height: 1.0, indent: 0.0, color: Color(0xFFe5e5e5))
)
);
@override
void dispose() {
super.dispose();
//eventBus.destroy();
//_subscription.resume(); // 开
//_subscription.pause(); // 暂停
_subscription.cancel(); // 取消
}
}
5、在第二个触发按钮事件中页面发送一个EventParam事件,这个时候,第一个界面就会立马更新
eventBus.fire(EventParam("110",'把无用同志发配到前一个页面'));
第二个页面代码
import 'package:flutter/material.dart';
import 'package:ydcflutter_app/common/test/CartModel.dart';
import 'package:ydcflutter_app/common/test/Item.dart';
import 'package:provider/provider.dart';
import 'package:ydcflutter_app/eventbus/YDCEventBusManage.dart';
import 'package:ydcflutter_app/eventbus/EventParam.dart';
import 'package:ydcflutter_app/test/EventBusTestPage1.dart';
class EventBusTestPage2 extends StatefulWidget {
@override
State createState() => new _EventBusTestPage2State();
}
class _EventBusTestPage2State extends State {
BuildContext mContext;
@override
void initState() {
// TODO: implement initState
super.initState();
}
void _onFire() {
//bus.emit("login",new EventParam("1",'把无用同志发配到前一个页面'));
eventBus.fire(EventParam("110",'把无用同志发配到前一个页面'));
}
@override
Widget build(BuildContext context) {
return new Scaffold( body:Center(
child: Builder(builder: (context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Builder(builder: (context) {
print("RaisedButton build"); //在后面优化部分会用到
return RaisedButton(
child: Text("使用EventBus更新上一个页面的数据"),
onPressed: () {
_onFire();
Navigator.of(context).pop();
},
);
}),
],
);
}),
),
);
}
Widget dividerWidget = new Container(
//margin: const EdgeInsets.only( left: 10.0,right: 10.0),
child: new Padding(
padding: const EdgeInsets.only(left: 0.0, right: 0.0),
child:
new Divider(height: 1.0, indent: 0.0, color: Color(0xFFe5e5e5))
)
);
@override
void dispose() {
super.dispose();
}
}
6、EventBus还可以用在以下场景:
1、单个页面里面的父子组件之间的通信
2、可以作为整个应用的全局事件,比如Http请求在某种code值下,刷新一个或多个界面。
Flutter商城项目实战:https://github.com/dechengyang/ydc_flutter_app
如果对你有帮助,随意赏我奶粉钱吧,多谢!
微信:
支付宝: