[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:...
    )
posted @ 2022-03-19 12:52  漫游者杰特  阅读(64)  评论(0编辑  收藏  举报