flutter自定义InheritedProvider实现状态管理详解

目录
  • InheritedWidget简单数据驱动模型
  • 1. 数据存储
  • 2. 变更通知
  • 3. 使用方法

InheritedWidget简单数据驱动模型

基于InheritedWidget,实现简单的数据驱动模型,模型结构如下:

1. 数据存储

使用 InheritedWidget,新建 InheritedProvider

import 'package:flutter/material.dart';
class InheritedProvider<T> extends InheritedWidget {
  final T data;
  InheritedProvider({@required this.data, Widget child}) : super(child: child);
  @override
  bool updateShouldNotify(InheritedProvider<T> oldWidget) {
    //在此简单返回true,则每次更新都会调用依赖其的子孙节点的 didChangeDependencies
    return true;
  }
}

2. 变更通知

使用flutter自带的 ChangeNotifier 组件,封装工具类 ChangeNotifierProvider 用于响应数据变更,触发UI更新。

class ChangeNotifierProvider<T extends ChangeNotifier> extends StatefulWidget {
  final Widget child;
  final T data; //共享的数据模型,要求继承ChangeNotifier
  const ChangeNotifierProvider({
    Key key,
    this.child,
    this.data,
  }) : super(key: key);
  ///提供方法,子树获取共享数据
  static T of<T>(BuildContext context) {
    final provider =
        context.dependOnInheritedWidgetOfExactType<InheritedProvider<T>>();
    return provider.data;
  }
  @override
  _ChangeNotifierProviderState createState() =>
      _ChangeNotifierProviderState<T>();
}
class _ChangeNotifierProviderState<T extends ChangeNotifier>
    extends State<ChangeNotifierProvider<T>> {
  ///如果数据发生变化(model类调用 notifyListeners),重新构建InheritedProvider
  void update() {
    setState(() => {});
  }
  @override
  void didUpdateWidget(ChangeNotifierProvider<T> oldWidget) {
    ///当Provider更新时,如果新旧数据不"==",则解绑旧数据监听,同时添加新数据监听
    if (widget.data != oldWidget.data) {
      oldWidget.data.removeListener(update);
      widget.data.addListener(update);
    }
    super.didUpdateWidget(oldWidget);
  }
  @override
  void initState() {
    widget.data.addListener(update);
    super.initState();
  }
  @override
  void dispose() {
    widget.data.removeListener(update);
    super.dispose();
  }
  @override
  Widget build(BuildContext context) {
    return InheritedProvider<T>(
      data: widget.data,
      child: widget.child,
    );
  }
}

原理:使用InheritedWidget作为父节点,当数据源更新时,数据模型经过ChangeNotifier的关联,触发 _ChangeNotifierProviderState 的 setState方法,刷新UI。

封装 NotifyConsumer 直接显式调用 ChangeNotifierProvider.of 获取共享数据语义不明确,我们将其做一层简单的封装用于子节点获取数据:

///响应数据变化的消费者
class NotifyConsumer<T> extends StatelessWidget {
  final Widget Function(BuildContext context, T value) builder;
  const NotifyConsumer({Key key, @required this.builder}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return builder(
      context,
      ChangeNotifierProvider.of<T>(context),
    );
  }
}

3. 使用方法

创建一个共享数据模型:

///共享数据模型
class CountModel extends ChangeNotifier {
  int _count = 0;
  int get count => _count;
  //提供自增方法
  void increase() {
    _count++;
    // 通知监听器(订阅者),重新构建InheritedProvider, 更新状态。
    notifyListeners();
  }
}

ChangeNotifierProvider 的使用方式:

import 'package:flutter/material.dart';
import 'package:test_interited/provider/change_notifier_provider.dart';
import 'package:test_interited/provider/notify_consumer.dart';
import 'package:test_interited/provider/test/count_model.dart';
class TestNotifierWidget extends StatefulWidget {
  const TestNotifierWidget({Key key}) : super(key: key);
  @override
  _TestNotifierWidgetState createState() => _TestNotifierWidgetState();
}
class _TestNotifierWidgetState extends State<TestNotifierWidget> {
  @override
  Widget build(BuildContext context) {
    return Center(
        child: ChangeNotifierProvider<CountModel>(
            data: CountModel(),
            child: Builder(builder: (context) {
              return Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Builder(
                    builder: (context) {
                      //获取共享数据源
                      return NotifyConsumer<CountModel>(
                          builder: (context, value) {
                        return Text(value.count.toString());
                      });
                    },
                  ),
                  Builder(builder: (context) {
                    return RaisedButton(
                      child: Text('自增'),
                      onPressed: () {
                        //获取共享model,进行数据自增操作
                        ChangeNotifierProvider.of<CountModel>(context).increase();
                      },
                    );
                  }),
                ],
              );
            })));
  }
}

以上就是flutter自定义InheritedProvider实现状态管理详解的详细内容,更多关于flutter自定义InheritedProvider的资料请关注我们其它相关文章!

(0)

相关推荐

  • Flutter 包管理器和资源管理使用学习

    目录 什么叫包管理器 Flutter 包管理器 Pub仓库 资源管理 配置图片资源 配置全局字体资源 结束语 什么叫包管理器 包管理器就是用来管理程序运行依赖的一个配置应用.在程序运行中,我们会用到各种各样的第三方程序包,若我们手动管理这些程序,他将变得十分臃肿.这时候便诞生了包管理器,类似于手机中的AppStore.比如说我们手机中的某个程序更新了,我们就可以通过AppStore来更新.同样的我们可以通过包管理来更新我们程序中用到的依赖包. Flutter 包管理器 Flutter包管理器是Y

  • flutter状态管理Provider的使用学习

    目录 1. provider的使用 2. 控制Widget的刷新颗粒度 3. 小结 本文主要介绍flutter中状态管理组件provider,provider: ^6.0.3主要是用于我们系统InheritedWidge的封装,用于数据的传递和管理. 1. provider的使用 网上也有很多关于provider说明,也可以看下官方的provider的 README.这里我记录一下我自己学习.我们对于简单的数据共享可以设置参数,之后子页面进行数据方法回调,从而完成数据间的通信.但是比较麻烦,下面

  • Flutter状态管理Provider的使用示例详解

    目录 前言 计数器 全局状态 总结 前言 Provider是三大主流状态管理框架官方推荐使用的框架,它是基于官方数据共享组件InheritedWidget实现的,通过数据改变调用生命周期中的didChangeDependencies()方法,来实现状态的通知改变. InheritedWidget的使用可以参考我之前的这篇Flutter中几种数据传递的应用总结. 计数器 还是以计数器为例,这次通过Provider实现,provider相较于bloc并没有那么强制性分层,所以这里我们自己分为数据层(

  • Flutter状态管理Bloc使用示例详解

    目录 前言 两种使用模式 Cubit模式 最后 前言 目前Flutter三大主流状态管理框架分别是provider.flutter_bloc.getx,三大状态管理框架各有优劣,本篇文章将介绍其中的flutter_bloc框架的使用,他是bloc设计思想模式在flutter上的实现,bloc全程全称 business logic ,业务逻辑的意思,核心思想就是最大程度的将页面ui与数据逻辑的解耦,使我们的项目可读性.可维护性.健壮性增强. 两种使用模式 首先第一步引入插件: flutter_bl

  • Flutter 状态管理scoped model源码解读

    目录 一.什么是 scoped_model 二.用法 三.实现原理 四.结束 一.什么是 scoped_model 本文主要从 scoped_model 的简单使用说起,然后再深入源码进行剖析(InheritedWidget.Listenable.AnimatedBuilder),不会探讨 Flutter 状态管理的优劣,单纯为了学习作者的设计思想. scoped_model 是一个第三方 Dart 库,可以让您轻松的将数据模型从父 Widget 传递到子 Widget.此外,它还会在模型更新时

  • 封装flutter状态管理工具示例详解

    目录 引言 RxBinder 代码实现 Demo 完美运行 引言 关于 Flutter 状态管理,公司项目使用的是Bloc方案.Bloc 其实本质上是 provider 的封装扩展库,整体通过 InheritedWidget .Notifier 外加 Stream中转实现状态变更通知. 关于 Bloc 实现原理,有兴趣的同学可以观看这篇文章 Bloc原理解析 RxBinder 撇开Bloc内部实现策略,小轰尝试基于数据驱动模型,自定义一套状态管理工具.构思如下: 主要成员如下: RxBinder

  • Flutter状态管理Provider示例解析

    目录 什么是状态管理 常见的状态管理框架有哪些 Provider Redux GetX Provider 使用 添加依赖 导入应用 定义需要共享的数据 在应用程序入口初始化 使用共享数据 状态管理的好处 结束语 什么是状态管理 状态管理是一个十分广泛的概念,因为状态无处不在.从广义角度讲状态管理就是页面跟代码.跟服务器进行数据同步.例如:你在某购物应用内,添加了一件商品,你需要在购物车页面进行展示.这就是一种状态.相反的,你在商品页面点击了添加到购物车,却在购物车页面没有发现或者过段时间它才展示

  • 详解Flutter 响应式状态管理框架GetX

    目录 一.状态管理框架对比 Provider BLoC GetX 二.基本使用 2.1 安装与引用 2.2 使用GetX改造Counter App 2.3 GetX代码插件 三.其他功能 3.1 路由管理 3.2 依赖关系管理 3.3 工具 3.4 改变主题 3.5 GetConnect 3.6 GetPage中间件 Priority Redirect onPageCalled OnBindingsStart OnPageBuildStart 3.7 全局设置和手动配置 3.8 StateMix

  • flutter自定义InheritedProvider实现状态管理详解

    目录 InheritedWidget简单数据驱动模型 1. 数据存储 2. 变更通知 3. 使用方法 InheritedWidget简单数据驱动模型 基于InheritedWidget,实现简单的数据驱动模型,模型结构如下: 1. 数据存储 使用 InheritedWidget,新建 InheritedProvider import 'package:flutter/material.dart'; class InheritedProvider<T> extends InheritedWidg

  • vue前端开发辅助函数状态管理详解示例

    目录 mapState mapGetters mapMutations mapActions 示例 小结 mapState 当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余.为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性.不使用mapState时,获取对象状态,通常放在使用组件的computes属性中,使用方式为: //.... computed: { count: function(){ return this.$store.state

  • 基于React Hooks的小型状态管理详解

    目录 实现基于 React Hooks 的状态共享 使用感受 本文主要介绍一种基于 React Hooks 的状态共享方案,介绍其实现,并总结一下使用感受,目的是在状态管理方面提供多一种选择方式. 实现基于 React Hooks 的状态共享 React 组件间的状态共享,是一个老生常谈的问题,也有很多解决方案,例如 Redux.MobX 等.这些方案很专业,也经历了时间的考验,但私以为他们不太适合一些不算复杂的项目,反而会引入一些额外的复杂度. 实际上很多时候,我不想定义 mutation 和

  • vue之使用vuex进行状态管理详解

    目录 vuex进行状态管理 vuex状态管理基本使用 vuex进行状态管理 首先学习vuex必须先知道vue原理 Vue是一个典型的MVVM框架,模型(Model)只是普通的JavaScript对象,修改它则视图(View)会自动更新.这种设计让状态管理变得非常简单而直观 Vue实现这种数据双向绑定的效果,需要三大模块: Observer:能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者 Compile:对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更

  • Mobx实现React 应用的状态管理详解

    目录 MobX 从一个 demo 开始 创建类并将其转化成可观察对象 使用可观察对象 MobX 与 React 集成 在组件中使用可观察对象 1. 访问全局的类实例 2. 通过 props 3. 通过 React Context 4. 在组件中实例化 observable class 并存储它的实例 5. 在组件中调用 observable 方法创建可观察对象 6. 在函数组件中使用 useLocalObservable 让组件具备观察能力 总结 MobX MobX 是一个状态管理库,它会自动收

  • vue3如何使用provide实现状态管理详解

    目录 前言 如何通过 provide/inject 实现 Vuex的功能 在应用中注册此插件 插件的入口文件 创建 store ,把对应的数据挂载到根组件上 实现 mapState.mapMutations 和 mapActions方法 组件中使用 总结 前言 在 Vue 生态中, Vuex 这个官方的状态管理库在 Vue 应用开发中,为我们带来了非常便捷的功能.但是 Vuex 20K+ 的大小,也带来了一些成本,对于项目规模较小的应用来说, 引入 Vuex 只是为了存储用户信息之类的一小撮数据

  • javascript Redux的状态管理详解

    所谓的状态管理,就是对应用程序中的数据进行管理. 理念:凡是数据流管理混乱的项目,几乎都上不了线.好的项目,必须有非常良好的数据流管理. 如何使用Redux?记住“3个3”. 第1个三:3个api,createStore.combineReducers.applyMiddleware 第2个三:3个特点,store单一数据源.store只读的.只能通过reducer纯函数来修改store. 第3个三:3个概念,store.action.reducer. 基本概念: state 包含所有数据,用来

  • Spring boot自定义http反馈状态码详解

    前言 最近在开发一些http server类型程序,通过spring boot构建一些web程序,这些web程序之间通过http进行数据访问.共享,如下图, 假设现在client发起一次保存数据的请求到server,server可能会返回如下类似的数据 { "status":1, "message":"xxxxxx" } 然后client通过解析json获得status来判断当前的请求操作是否成功,开发过程中通过都是这么做的,但是这样在restf

  • django站点管理详解

    管理界面是基础设施中非常重要的一部分.这是以网页和有限的可信任管理者为基础的界面,它可以让你添加,编辑和删除网站内容.Django有自己的自动管理界面.这个特性是这样起作用的:它读取你模式中的元数据,然后提供给你一个强大而且可以使用的界面,网站管理者可以用它立即工作. Django的管理员模块是Django的标准库django.contrib的一部分.这个包还包括其它一些实用的模块: django.contrib.auth django.contrib.sessions django.contr

  • Flutter实现底部导航栏创建详解

    目录 添加依赖项 如何使用 功能 属性 主题 预览图 代码 Flutter web问题:Failed to load network image 我的解决办法 参考资料 ConvexBottomBar是一个底部导航栏组件,用于展现凸起的TAB效果,支持多种内置样式与动画交互.你可以在https://appbar.codemagic.app/上找到在线样例. 添加依赖项 在你的项目中去 pubspec.添加依赖项: 添加https://pub.dev/packages/convex_bottom_

随机推荐