Flutter Provider状态管理---介绍、类图分析、基本使用

文章系列

Flutter Provider状态管理---介绍、类图分析、基本使用

Flutter Provider状态管理---八种提供者使用分析

Flutter Provider状态管理---四种消费者使用分析

Flutter Provider状态管理---MVVM架构实战

视频系列

Flutter Provider状态管理---介绍、类图分析、基本使用

Flutter Provider状态管理---八种提供者使用分析

Flutter Provider状态管理---四种消费者使用分析

Flutter Provider状态管理---MVVM架构实战

源码仓库地址

github仓库地址

介绍

Provider是一个由社区构建的状态管理包,而不是Google推出,但ProviderGoogle极力推荐的状态管理方式之一,它是对InheritedWidget组件进行了封装,使其更易用,更易复用。

学习本章节前,希望你能了解如下知识:

  • 熟悉dart语言
  • 熟悉flutter基本组件
  • 了解InheritedWidget
  • 了解ChangeNotifier

如果大家大家之前没接触过InheritedWidget,那么建议你先去了解,你可以通过链接来查看并掌握对应的只是 英文官方文档 中文官方文档 源码分析 视频教程

Provider优势

我们为什么要用Provider而不是直接使用InheritedWidget,我们看下官方介绍

  • 简化的资源分配与处置
  • 懒加载
  • 创建新类时减少大量的模板代码
  • 支持 DevTools
  • 更通用的调用 InheritedWidget 的方式(参考 Provider.of/Consumer/Selector
  • 提升类的可扩展性,整体的监听架构时间复杂度以指数级增长(如 ChangeNotifier, 其复杂度为 O(N))

Provider类结构图

image

Provider类说明

Nested组件

  • Nested: 简化树结构嵌套过深
  • SingleChildWidget: 单个子组件的组件,但是它与ProxyWidget不同,有一个build方法。
  • SingleChildStatelessWidget: 它是一个实现SingleChildWidgetStatelessWidget,必须使用buildWithChild构建子组件
  • SingleChildStatefulWidget: 它是一个实现SingleChildWidgetStatefulWidget,是与Nested兼容的StatefulWidget

Provider组件

Provider组件分为四大类,分别如下:

Nested系列

MultiProvider: 主要作用是提高代码可读性和减少重复代码,是将多个提供者合并成单个线性的组件提供者。

SingleChildStatefulWidget系列

  • Selector0: 它是Selector至Selector6的基类
  • Selector1-6: 它们是将Selector0Provider.of结合使用的语法糖,继承自Selector0

SingleChildStatelessWidget系列

  • Consumer1-6: 消费者,只是调用了Provider.of,主要作用是从顶层获取Provider<T>并将其值传递给了builder
  • InheritedProvider: InheritedWidget的通用实现,并且所有的继承自该类的都可以通过Provider.of来获取value
  • DeferredInheritedProvider: InheritedProvider的子类,用于监听流或者接收一个Future
  • StreamProvider: 监听流,并暴露出当前的最新值。
  • FutureProvider: 接收一个 Future,并在其进入 complete 状态时更新依赖它的组件。
  • ListenableProvider: 供可监听对象使用的特殊 providerListenableProvider 会监听对象,并在监听器被调用时更新依赖此对象的widgets
  • ChangeNotifierProvider:ChangeNotifier 提供的 ListenableProvider规范,会在需要时自动调用 ChangeNotifier.dispose
  • ListenableProxyProvider0: 可见的代理提供者,主要是从其他提供者获取值。
  • ListenableProxyProvider1-6: 它是ListenableProvider的一个变体,继承ListenableProxyProvider0, 从其他提供者获取值
  • ChangeNotifierProxyProvider0: 主要用于构建和同步ChangeNotifierChangeNotifierProvider
  • Provider: 最基础的 provider 组成,接收一个任意值并暴露它。
  • ProxyProvider0: 它公开的值会通过创建或更新构建,然后传递给 InheritedProvider
  • ProxyProvider1-6: ProxyProvider0的语法糖。

InheritedContext系列

  • InheritedContext:InheritedProvider关联的BuildContext,提供公开的值
  • ReadContext: 公开读取方法
  • SelectContext: 在 BuildContext 上添加一个选择方法。
  • WatchContext: 公开 watch 方法。

Provider基本使用

第一步:添加依赖

本文中所有的代码都是基本空安全的,所有dart sdk版本为>=2.12.0 <3.0.0,目前官方最新版本为^6.0.1

environment:
  sdk: ">=2.12.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter

  provider: ^6.0.1

第二步:定义需要共享的数据

我们这里创建了一个类CountNotifier继承了ChangeNotifier,我们这里的案例是以计数器为案例,所有我们定义一个变量count,以及一个改变数值的increment方法,当我们调用increment后会对count进行+1,最后调用notifyListeners()来更新数据,代码如下:

import 'package:flutter/material.dart';

class CountNotifier with ChangeNotifier {

  int count = 0;

  void increment() {
    count++;
    notifyListeners();
  }
}

第三步:在应用程序入口初始化

我们在MaterialApp之前对定义的共享数据进行了初始化,代码如下:

import 'package:flutter/material.dart';
import 'package:flutter_provider_example/provider_count_example/count_notifier.dart';
import 'package:flutter_provider_example/provider_count_example/provider_count_example.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (_) => CountNotifier(),
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        home: ProviderCountExample(),
      ),
    );
  }
}

第四步:使用共享数据

我们定义了一个counter变量来获取到共享的数据,更新数据的方法直接通过counter.increment(),获取数据的方法通过ounter.count.toString()来获取,代码如下:

import 'package:flutter/material.dart';
import 'package:flutter_provider_example/provider_count_example/count_notifier.dart';
import 'package:provider/provider.dart';

class ProviderCountExample extends StatefulWidget {
  @override
  _ProviderCountExampleState createState() => _ProviderCountExampleState();
}

class _ProviderCountExampleState extends State<ProviderCountExample> {

  @override
  Widget build(BuildContext context) {

    final counter = Provider.of<CountNotifier>(context);

    return Scaffold(
      appBar: AppBar(
        title: Text("InheritedWidget"),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: (){
          counter.increment();
        },
        child: Icon(Icons.add),
      ),
      body: Center(
        child: Text(counter.count.toString(),
          style: TextStyle(
              color: Colors.red,
              fontSize: 50
          ),
        ),
      ),
    );
  }
}

总结

以上是对Provider进行了介绍、优势、类结构和说明以及一个基本使用的例子,相对于使用InheritedWidget来说,显然Provider使用起来更简单。但是从它的提供者、消费者这些类来看稍微复杂,后面的章节中我们来讲讲这些类

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容