前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Flutter 组件集录 | SharedAppData 应用数据共享

Flutter 组件集录 | SharedAppData 应用数据共享

作者头像
张风捷特烈
发布2024-03-12 12:07:52
880
发布2024-03-12 12:07:52
举报

上一篇 《Flutter 组件集录 | InheritedModel 共享模型 》介绍了 InheritedModel 通过定义 Aspect(方面) 来更精细地控制依赖更新的粒度。本文看一下基于 InheritedModel 实现的 SharedAppData 组件,如何实现应用级数据的共享。

本组件案例已收录到 FlutterUnit:源码可详见 【 SharedAppData/node1.dart】


1.认识 SharedAppData 组件

SharedAppData 是新增的组件,其价值是提供键值对的映射关系,让子树节点可以访问数据。和 MediaQuery 、Theme、Navigator 组件类似,SharedAppData 组件也是内置在 WidgetsApp 状态类构建逻辑之中的。

image.png
image.png

也就是说,当使用 MaterialApp 时,组件树种会提供默认的 SharedAppData 组件,我们一般并不需要主动创建它:

image.png
image.png

2. 使用 SharedAppData 组件

还是拿这个例子说明共享 颜色数值 的场景。SharedAppData 的使用包括:

  • 1. 如何访问读取数据。
  • 2. 如何更新设置数据。
47.gif
47.gif

SharedAppData 提供了 getValue 静态方法,可以让使用者通过上下文和键访问数据;如果键的值不存在,在回调中将返回初始值:

代码语言:javascript
复制
@override
Widget build(BuildContext context) {
  final Color color = SharedAppData.getValue<String, Color>(context, 'color', () => Colors.black);
  final int counter = SharedAppData.getValue<String, int>(context, 'counter', () => 0);
  return Text(
    "Counter = $counter",
    style: TextStyle(color: color,fontWeight: FontWeight.bold),
  );
}

SharedAppData 提供了 setValue 静态方法,可以让使用者通过上下文和键设置数据。在设置值时,通过该键读取过值的 context,将会被通知更新 (无需 setState) 。

代码语言:javascript
复制
void _onSelectColor(Color value) {
  SharedAppData.setValue<String, Color?>(context, 'color', value);
}

SharedAppData 的底层基于 InheritedModel 实现的,它将 key 视为方面,所以也具有精确控制粒度的能力。比如仅修改数字时,没有依赖数字 key 的 BoxDecorationWrap,其对应的元素将不会被通知更新。

代码语言:javascript
复制
---->[修改颜色时]----
flutter: ======BoxDecorationWrap#didChangeDependencies=========
flutter: ======CounterText#didChangeDependencies=========

---->[修改数字时]----
flutter: ======CounterText#didChangeDependencies=========

这就是 SharedAppData 所有的功能,它的目的很明确,就是:

向子树共享键值对数据,在更新数据时,通知所有依赖过 key 访问数据的 context 元素更新。

源码中对 SharedAppData 的介绍在表示: 它并不是替代 Provider 或任何其他状态管理系统的方案。一般会通过 SharedAppData 共享 package 内的,一个或几个可以惰性初始化的不可变数据对象。


4. SharedAppData 的源码实现

SharedAppData 是一个 StatefulWidget,其中定义了 setValuegetValue 两个静态方法;通过 _SharedAppDataState 状态类处理组件的构建任务。

image.png
image.png

_SharedAppDataState 中维护一个映射 data 对象,用于存储键值对,构建逻辑中返回 _SharedAppModel 组件:

代码语言:javascript
复制
class _SharedAppDataState extends State<SharedAppData> {
  late Map<Object, Object?> data = <Object, Object?>{};

  @override
  Widget build(BuildContext context) {
    return _SharedAppModel(sharedAppDataState: this, child: widget.child);
  }

  V getValue<K extends Object, V>(K key, SharedAppDataInitCallback<V> init) {
    data[key] ??= init();
    return data[key] as V;
  }

  void setValue<K extends Object, V>(K key, V value) {
    if (data[key] != value) {
      setState(() {
        data = Map<Object, Object?>.of(data);
        data[key] = value;
      });
    }
  }
}

_SharedAppModel 组件就是 InheritedModel 的派生类,负责存储数据,通过上下文向子树共享数据。在 updateShouldNotifyDependent 回调方法的处理中可以看出,数据的 key 被视为数据的 Aspect。只有依赖者使用到相关的 key, 当 key 对应数据发生变化时,才会通知该依赖者。

代码语言:javascript
复制
class _SharedAppModel extends InheritedModel<Object> {
  _SharedAppModel({
    required this.sharedAppDataState,
    required super.child
  }) : data = sharedAppDataState.data;

  final _SharedAppDataState sharedAppDataState;
  final Map<Object, Object?> data;

  @override
  bool updateShouldNotify(_SharedAppModel old) {
    return data != old.data;
  }

  @override
  bool updateShouldNotifyDependent(_SharedAppModel old, Set<Object> keys) {
    for (final Object key in keys) {
      if (data[key] != old.data[key]) {
        return true;
      }
    }
    return false;
  }
}

这就是 SharedAppData 的所有源码内容,总的来看它的作用非常明确,向子树共享键值对数据。由于 MaterialApp 已经内置 SharedAppData,所以在应用中直接通过静态方法存取数据即可。那本文就到这里,谢谢观看 ~

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-03-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.认识 SharedAppData 组件
  • 2. 使用 SharedAppData 组件
  • 4. SharedAppData 的源码实现
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档