感谢各位提醒只可以通知一个页面的问题
为何需要广播通知传值?
假如有一个需求是这样的,导航有三个页面,第一页有一个按钮跳到第二页,第二页有一个按钮跳到第三页,第三页有个按钮来改变第一页的背景色。这时候就可以通过通知传值的方式。在第一页添加一个通知监听者,第三页发送通知告知第一页。
效果如下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<String, dynamic> _postNameMap = Map<String, dynamic>();
//添加监听者方法
Widget addObserver(String postName,Widget Function(dynamic)calllback) {
if (_postNameMap[postName] == null) {
_postNameMap[postName] = StreamController<dynamic>.broadcast();
}
return StreamBuilder<dynamic>(
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);
最后
代码可能写的不好,只是提供一个自己的想法。