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

 更新时间:2022年11月14日 16:53:19   作者:李小轰_Rex  
这篇文章主要为大家介绍了flutter自定义InheritedProvider实现状态管理详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

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的资料请关注脚本之家其它相关文章!

相关文章

  • android照相、相册获取图片剪裁报错的解决方法

    android照相、相册获取图片剪裁报错的解决方法

    最近在项目中用到了照相和相册取图剪裁上传头像,就在网上逛了逛,基本都是千篇一律,就弄下来用了用,没想到的是各种各样的奇葩问题就出现了。先给大家看看代码问题慢慢来解决
    2014-11-11
  • Android学习之BottomSheetDialog组件的使用

    Android学习之BottomSheetDialog组件的使用

    BottomSheetDialog是底部操作控件,可在屏幕底部创建一个支持滑动关闭视图。本文将通过示例详细讲解它的使用,感兴趣的小伙伴可以了解一下
    2022-06-06
  • Android实现图片滚动效果

    Android实现图片滚动效果

    这篇文章主要为大家详细介绍了Android实现图片滚动效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-09-09
  • Android实现拍照添加时间水印

    Android实现拍照添加时间水印

    这篇文章主要为大家详细介绍了Android实现拍照添加时间水印,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • Android开屏页倒计时功能实现的详细教程

    Android开屏页倒计时功能实现的详细教程

    本篇文章主要介绍了Android实现开屏页倒计时功能实现的详细教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • 解决Android Studio xml 格式化不自动换行的问题

    解决Android Studio xml 格式化不自动换行的问题

    这篇文章主要介绍了解决Android Studio xml 格式化不自动换行的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-03-03
  • Webview实现android简单的浏览器实例代码

    Webview实现android简单的浏览器实例代码

    这篇文章主要介绍了Webview实现android简单的浏览器实例代码的相关资料,需要的朋友可以参考下
    2016-02-02
  • Android Studio升级到4.1以后插件问题解决

    Android Studio升级到4.1以后插件问题解决

    这篇文章主要介绍了Android Studio升级到4.1以后插件问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • android 更改TextView中任意位置字体大小和颜色的方法

    android 更改TextView中任意位置字体大小和颜色的方法

    下面小编就为大家分享一篇android 更改TextView中任意位置字体大小和颜色的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-01-01
  • Android触摸事件传递图解

    Android触摸事件传递图解

    这篇文章主要一图文结合的方式为大家详细介绍了Android触摸事件传递,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-01-01

最新评论