Flutter模仿iOS通知传值(封装StreamController)

感谢各位提醒只可以通知一个页面的问题

为何需要广播通知传值?

假如有一个需求是这样的,导航有三个页面,第一页有一个按钮跳到第二页,第二页有一个按钮跳到第三页,第三页有个按钮来改变第一页的背景色。这时候就可以通过通知传值的方式。在第一页添加一个通知监听者,第三页发送通知告知第一页。

效果如下gif:

Untitled.gif

思路

我的思路是创建一个单例类,在你需要监听的页面创建这个监听者。在需要发送通知的页面也继续创建这个单例类,通过回调的方式传递值。

代码

创建一个单例类

import 'dart:async';

import 'package:flutter/cupertino.dart';

class NotificationCenter {
  // 工厂模式
  factory NotificationCenter() => _getInstance()!;

  static NotificationCenter? get instance => _getInstance();
  static NotificationCenter? _instance;

  NotificationCenter._internal() {
    // 初始化
  }

  static NotificationCenter? _getInstance() {
    if (_instance == null) {
      _instance = new NotificationCenter._internal();
    }
    return _instance;
  }

  //创建Map来记录名称
  Map _postNameMap = Map();


  //添加监听者方法
  Widget addObserver(String postName,Widget Function(dynamic)calllback) {

    if (_postNameMap[postName] == null) {

      _postNameMap[postName] = StreamController.broadcast();
    }


    return StreamBuilder(

      stream: _postNameMap[postName].stream,
      builder: (context,snap){

        return calllback(snap.data);
      },
    );
  }

  //发送通知传值
  postNotification(String postName, dynamic object) {
    //检索Map是否含有postName
    if (_postNameMap.containsKey(postName)) {

      _postNameMap[postName].add(object);
    }

  }
}

在首页添加一个监听

//添加监听者
NotificationCenter.instance!.addObserver("change_color",(object){
//这里返回一个你需要局部改变的页面
        return Container(

          alignment: Alignment.center,
          color: object == null ?  Colors.amberAccent : object,
          child: ElevatedButton(onPressed: () {

            Navigator.push(context, MaterialPageRoute(builder: (context){


              return SecondPage();
            }));

          }, child: Text('下一页'),),
        );
      })

在第三页发送通知


//通知将所有监听的页面背景色变成红色
NotificationCenter.instance!.postNotification("change_color", Colors.red);

最后

代码可能写的不好,只是提供一个自己的想法。

你可能感兴趣的:(Flutter模仿iOS通知传值(封装StreamController))