Flutter 跳转多个页面后回到第一个页面并实现参数传递

路漫漫其修远兮,吾将上下而求索。——屈原

一年一度的清明节又到了。2020年是多灾多难的一年,生活不容易呀。

                                      

最近开发的项目有关需求就是跳转多个页面后,需要一键回到首页。对移动端原生比较熟悉的同学大概知道怎么去实现。若用Flutter就会用到路由跳转。Route在Android通常指一个Activity,在ios中指ViewController。所谓的路由管理,就是管理页面之间的跳转。路由入栈(push)打开一个管理页面,路由出栈(pop)操作对应关闭页面。

第一步:继承自 StatelessWidget 的函数 build 注册相关路由:

 @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '应用名称',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MainTabBarWidget(),
      routes: <String, WidgetBuilder>{
        '/Route1': (BuildContext context) => new RoutePage1(),
        '/Route2': (BuildContext context) => new RoutePage2(),
        '/Route3': (BuildContext context) => new RoutePage3(),
        '/Route4': (BuildContext context) => new RoutePage4(),
      },
    );
  }

第二步:路由导航

 navigatorToRoutePage(BuildContext _buildContext, StatefulWidget _baseWidget, _routeName) {
    Navigator.push(
      _buildContext,
      MaterialPageRoute(
        settings: RouteSettings(name: _routeName),
        builder: (context) => _baseWidget,
      ),
    );
  }

第三步:回退到第一个路由

Navigator.popUntil(context, ModalRoute.withName('/'));

完成以上三个步骤后,接下来,我们需要实现接受栈顶路由传递的值。

思路:

1、我们将参数从路由Route4传递到Route3再到Route2再到Route1,虽然可以实现有点麻烦。

2、我们可以建立本次存储,然后关闭Route4的时候保存数据,在Route1显示时获取数据,麻烦。

3、Route1定义一个全局变量,然后单例获取Route1实例并修改Route1全局参数的值,麻烦。

4、我们今天要说的就是事件传递EventBus。

其实在原生开发中最初是广播(BrocasetReceiver)到后来的EventBus,其实不管是框架还是以某种语言发明的技能都会互相借鉴原理。

//订阅者回调签名
typedef void EventCallback(arg);

class EventBus {
  //私有构造函数
  EventBus._internal();

  //保存单例
  static EventBus _singleton = new EventBus._internal();

  //工厂构造函数
  factory EventBus()=> _singleton;

  //保存事件订阅者队列,key:事件名(id),value: 对应事件的订阅者队列
  var _emap = new Map<Object, List<EventCallback>>();

  //添加订阅者
  void on(eventName, EventCallback f) {
    if (eventName == null || f == null) return;
    _emap[eventName] ??= new List<EventCallback>();
    _emap[eventName].add(f);
  }

  //移除订阅者
  void off(eventName, [EventCallback f]) {
    var list = _emap[eventName];
    if (eventName == null || list == null) return;
    if (f == null) {
      _emap[eventName] = null;
    } else {
      list.remove(f);
    }
  }

  //触发事件,事件触发后该事件所有订阅者会被调用
  void emit(eventName, [arg]) {
    var list = _emap[eventName];
    if (list == null) return;
    int len = list.length - 1;
    //反向遍历,防止订阅者在回调中移除自身带来的下标错位 
    for (var i = len; i > -1; --i) {
      list[i](arg);
    }
  }
}

//定义一个top-level(全局)变量,页面引入该文件后可以直接使用bus
var bus = new EventBus();

使用事件分发

//Page 1、2、3、4中
...
 
bus.on("约定享受事件的标记", (arg) {
  // do something
});
向订阅界面发送参数
...
//
bus.emit("约定享受事件的标记", "传递的参数");

参考:

事件总线:https://book.flutterchina.club/chapter8/eventbus.html?h=EventBus

路由:https://book.flutterchina.club/chapter2/flutter_router.html?h=%E8%B7%AF%E7%94%B1

Material Design 中文版http://www.apkbus.com/design/selection.html

发布了22 篇原创文章 · 获赞 17 · 访问量 6932

猜你喜欢

转载自blog.csdn.net/u013491829/article/details/105313600