感謝各位提醒只可以通知一個(gè)頁(yè)面的問(wèn)題
為何需要廣播通知傳值?
假如有一個(gè)需求是這樣的,導(dǎo)航有三個(gè)頁(yè)面,第一頁(yè)有一個(gè)按鈕跳到第二頁(yè),第二頁(yè)有一個(gè)按鈕跳到第三頁(yè),第三頁(yè)有個(gè)按鈕來(lái)改變第一頁(yè)的背景色。這時(shí)候就可以通過(guò)通知傳值的方式。在第一頁(yè)添加一個(gè)通知監(jiān)聽(tīng)者,第三頁(yè)發(fā)送通知告知第一頁(yè)。
效果如下gif:

Untitled.gif
思路
我的思路是創(chuàng)建一個(gè)單例類,在你需要監(jiān)聽(tīng)的頁(yè)面創(chuàng)建這個(gè)監(jiān)聽(tīng)者。在需要發(fā)送通知的頁(yè)面也繼續(xù)創(chuàng)建這個(gè)單例類,通過(guò)回調(diào)的方式傳遞值。
代碼
創(chuàng)建一個(gè)單例類
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;
}
//創(chuàng)建Map來(lái)記錄名稱
Map<String, dynamic> _postNameMap = Map<String, dynamic>();
//添加監(jiān)聽(tīng)者方法
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);
},
);
}
//發(fā)送通知傳值
postNotification(String postName, dynamic object) {
//檢索Map是否含有postName
if (_postNameMap.containsKey(postName)) {
_postNameMap[postName].add(object);
}
}
}
在首頁(yè)添加一個(gè)監(jiān)聽(tīng)
//添加監(jiān)聽(tīng)者
NotificationCenter.instance!.addObserver("change_color",(object){
//這里返回一個(gè)你需要局部改變的頁(yè)面
return Container(
alignment: Alignment.center,
color: object == null ? Colors.amberAccent : object,
child: ElevatedButton(onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context){
return SecondPage();
}));
}, child: Text('下一頁(yè)'),),
);
})
在第三頁(yè)發(fā)送通知
//通知將所有監(jiān)聽(tīng)的頁(yè)面背景色變成紅色
NotificationCenter.instance!.postNotification("change_color", Colors.red);
最后
代碼可能寫的不好,只是提供一個(gè)自己的想法。