[Flutter] InheritedWidget&Notification
InheritedWidget&Notification
说明:
InheritedWidget用来从上往下共享数据,通过context流通
Notification用来从下往上分发通知,通过context流通
完整示例demo
InheritedWidget
定义一个类“A”继承InheritedWidget,这个A类的构造函数有两个必传的参数,一个是共享的数据,
一个是child,child用来包裹顶层组件,从而往下共享数据,共享数据通过context流动从上往下流动,
遇到分支,分支的子组件也都会拿到数据。
下面的子组件通过A.of(context)来获取共享的数据。
STEP01
///定义需要共享的数据
class DataState{
bool status;
String message;
DataState({this.status=false,this.message='new message'});
}
STEP02
///定义一个类继承InheritedWidget
import 'package:demo_inherited/state.dart';
import 'package:flutter/cupertino.dart';
class ShareWidget extends InheritedWidget {
///保存共享数据的实例
final DataState shareData;
/// 构造函数
const ShareWidget({
Key? key,
required this.shareData,
required Widget child,
}) : super(key: key, child: child);
///直接返回实例,这样view页面shareWidget.of(context)==shareData
static DataState? of(BuildContext context) {
final ShareWidget? shareWidget =
context.dependOnInheritedWidgetOfExactType<ShareWidget>();
return shareWidget?.shareData;
}
//该回调决定当状态发生变化时,是否通知子树中依赖的该组件
@override
bool updateShouldNotify(ShareWidget oldWidget) {
// 是否需要更新,返回true则更新
// 当返回true时,如果在子child的build函数中有调用of获取该InheritedWidget,
// 那么这个子widget的`state.didChangeDependencies`方法会被调用
return this.shareData!= oldWidget.shareData;
}
}
STEP03
///包裹materialAPP,从顶层共享数据,设置数据的初始值
@override
Widget build(BuildContext context) {
return ShareWidget(shareData:DataState(status: false,message: '已读'), child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
));
}
STEP04
///拿取数据
Badge(
///ShareWidget.of(context)是返回的shareData实例
showBadge: ShareWidget.of(context)?.status??false,
badgeColor: Colors.red,
child: const Text('消息',style: TextStyle(fontSize: 20),)),
STEP05
///修改数据
InkWell(
onTap: (){
setState(() {
ShareWidget.of(context)!.message='已读';
ShareWidget.of(context)!.status=false;
});
},
Notification
定义一个类“B”继承Notification,把这个B类的NotificationListener放在任意位置,这个监听器下面的子组件(通过context流动,同级接收不到)的消息就能往上冒泡,可以设置多个NotificationListener来监听冒泡上来的消息,NotificationListener方法return的false就是放通消息,上一层的组件也能收到冒泡上来的消息,是true就是拦截消息,使其不再往上冒泡。
STEP01
///定义MyNotification继承Notification
///定义需要分发通知的消息msg
import 'package:flutter/material.dart';
class MyNotification extends Notification{
final String msg;
MyNotification(this.msg);
}
STEP02
///分发消息,开始往上冒泡
InkWell(
onTap: (){
MyNotification("refresh").dispatch(context);
},
STEP03
///监听冒泡上来的消息,onNotification接收到消息后处理的方法
return NotificationListener<MyNotification>(
onNotification: (notification) {
print(notification.msg);
setState(() {});
///return true即不再往上冒泡
return true;
},
child:...
)