文章系列
Flutter Provider狀態(tài)管理---介紹、類圖分析、基本使用
Flutter Provider狀態(tài)管理---八種提供者使用分析
Flutter Provider狀態(tài)管理---四種消費(fèi)者使用分析
Flutter Provider狀態(tài)管理---MVVM架構(gòu)實(shí)戰(zhàn)
視頻系列
Flutter Provider狀態(tài)管理---介紹、類圖分析、基本使用
Flutter Provider狀態(tài)管理---八種提供者使用分析
Flutter Provider狀態(tài)管理---四種消費(fèi)者使用分析
Flutter Provider狀態(tài)管理---MVVM架構(gòu)實(shí)戰(zhàn)
源碼倉庫地址
介紹
Provider是一個(gè)由社區(qū)構(gòu)建的狀態(tài)管理包,而不是Google推出,但Provider是Google極力推薦的狀態(tài)管理方式之一,它是對InheritedWidget組件進(jìn)行了封裝,使其更易用,更易復(fù)用。
學(xué)習(xí)本章節(jié)前,希望你能了解如下知識:
- 熟悉dart語言
- 熟悉flutter基本組件
- 了解InheritedWidget
- 了解ChangeNotifier
如果大家大家之前沒接觸過InheritedWidget,那么建議你先去了解,你可以通過鏈接來查看并掌握對應(yīng)的只是 英文官方文檔 中文官方文檔 源碼分析 視頻教程
Provider優(yōu)勢
我們?yōu)槭裁匆?code>Provider而不是直接使用InheritedWidget,我們看下官方介紹
- 簡化的資源分配與處置
- 懶加載
- 創(chuàng)建新類時(shí)減少大量的模板代碼
- 支持 DevTools
- 更通用的調(diào)用 InheritedWidget 的方式(參考 Provider.of/Consumer/Selector)
- 提升類的可擴(kuò)展性,整體的監(jiān)聽架構(gòu)時(shí)間復(fù)雜度以指數(shù)級增長(如 ChangeNotifier, 其復(fù)雜度為 O(N))
Provider類結(jié)構(gòu)圖

Provider類說明
Nested組件
- Nested: 簡化樹結(jié)構(gòu)嵌套過深
-
SingleChildWidget: 單個(gè)子組件的組件,但是它與
ProxyWidget不同,有一個(gè)build方法。 -
SingleChildStatelessWidget: 它是一個(gè)實(shí)現(xiàn)
SingleChildWidget的StatelessWidget,必須使用buildWithChild構(gòu)建子組件 -
SingleChildStatefulWidget: 它是一個(gè)實(shí)現(xiàn)
SingleChildWidget的StatefulWidget,是與Nested兼容的StatefulWidget
Provider組件
Provider組件分為四大類,分別如下:
Nested系列
MultiProvider: 主要作用是提高代碼可讀性和減少重復(fù)代碼,是將多個(gè)提供者合并成單個(gè)線性的組件提供者。
SingleChildStatefulWidget系列
- Selector0: 它是Selector至Selector6的基類
-
Selector1-6: 它們是將
Selector0與Provider.of結(jié)合使用的語法糖,繼承自Selector0
SingleChildStatelessWidget系列
-
Consumer1-6: 消費(fèi)者,只是調(diào)用了
Provider.of,主要作用是從頂層獲取Provider<T>并將其值傳遞給了builder。 -
InheritedProvider:
InheritedWidget的通用實(shí)現(xiàn),并且所有的繼承自該類的都可以通過Provider.of來獲取value -
DeferredInheritedProvider:
InheritedProvider的子類,用于監(jiān)聽流或者接收一個(gè)Future - StreamProvider: 監(jiān)聽流,并暴露出當(dāng)前的最新值。
-
FutureProvider: 接收一個(gè)
Future,并在其進(jìn)入complete狀態(tài)時(shí)更新依賴它的組件。 -
ListenableProvider: 供可監(jiān)聽對象使用的特殊
provider,ListenableProvider會(huì)監(jiān)聽對象,并在監(jiān)聽器被調(diào)用時(shí)更新依賴此對象的widgets。 -
ChangeNotifierProvider: 為
ChangeNotifier提供的ListenableProvider規(guī)范,會(huì)在需要時(shí)自動(dòng)調(diào)用ChangeNotifier.dispose。 - ListenableProxyProvider0: 可見的代理提供者,主要是從其他提供者獲取值。
-
ListenableProxyProvider1-6: 它是
ListenableProvider的一個(gè)變體,繼承ListenableProxyProvider0, 從其他提供者獲取值 -
ChangeNotifierProxyProvider0: 主要用于構(gòu)建和同步
ChangeNotifier的ChangeNotifierProvider。 - Provider: 最基礎(chǔ)的 provider 組成,接收一個(gè)任意值并暴露它。
-
ProxyProvider0: 它公開的值會(huì)通過創(chuàng)建或更新構(gòu)建,然后傳遞給
InheritedProvider。 -
ProxyProvider1-6:
ProxyProvider0的語法糖。
InheritedContext系列
-
InheritedContext: 與
InheritedProvider關(guān)聯(lián)的BuildContext,提供公開的值 - ReadContext: 公開讀取方法
- SelectContext: 在 BuildContext 上添加一個(gè)選擇方法。
- 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
第二步:定義需要共享的數(shù)據(jù)
我們這里創(chuàng)建了一個(gè)類CountNotifier繼承了ChangeNotifier,我們這里的案例是以計(jì)數(shù)器為案例,所有我們定義一個(gè)變量count,以及一個(gè)改變數(shù)值的increment方法,當(dāng)我們調(diào)用increment后會(huì)對count進(jìn)行+1,最后調(diào)用notifyListeners()來更新數(shù)據(jù),代碼如下:
import 'package:flutter/material.dart';
class CountNotifier with ChangeNotifier {
int count = 0;
void increment() {
count++;
notifyListeners();
}
}
第三步:在應(yīng)用程序入口初始化
我們在MaterialApp之前對定義的共享數(shù)據(jù)進(jìn)行了初始化,代碼如下:
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(),
),
);
}
}
第四步:使用共享數(shù)據(jù)
我們定義了一個(gè)counter變量來獲取到共享的數(shù)據(jù),更新數(shù)據(jù)的方法直接通過counter.increment(),獲取數(shù)據(jù)的方法通過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
),
),
),
);
}
}
總結(jié)
以上是對Provider進(jìn)行了介紹、優(yōu)勢、類結(jié)構(gòu)和說明以及一個(gè)基本使用的例子,相對于使用InheritedWidget來說,顯然Provider使用起來更簡單。但是從它的提供者、消費(fèi)者這些類來看稍微復(fù)雜,后面的章節(jié)中我們來講講這些類