Flutter狀態(tài)管理Provider的使用示例詳解
前言
Provider是三大主流狀態(tài)管理框架官方推薦使用的框架,它是基于官方數(shù)據(jù)共享組件InheritedWidget
實(shí)現(xiàn)的,通過(guò)數(shù)據(jù)改變調(diào)用生命周期中的didChangeDependencies()
方法,來(lái)實(shí)現(xiàn)狀態(tài)的通知改變。
InheritedWidget
的使用可以參考我之前的這篇Flutter中幾種數(shù)據(jù)傳遞的應(yīng)用總結(jié)。
計(jì)數(shù)器
還是以計(jì)數(shù)器為例,這次通過(guò)Provider
實(shí)現(xiàn),provider
相較于bloc
并沒(méi)有那么強(qiáng)制性分層,所以這里我們自己分為數(shù)據(jù)層(state)、邏輯處理層(provider)、UI層(view)。
首先創(chuàng)建文件夾:
數(shù)據(jù)層: 用來(lái)保存數(shù)據(jù),基本和bloc
一樣。
/// 數(shù)據(jù)層 class PNumState { int num; // 初始化 PNumState({this.num = 0}); PNumState clone() { // 獲取最新對(duì)象 return PNumState()..num = num; } }
業(yè)務(wù)邏輯層 ChangeNotifier: 用來(lái)處理頁(yè)面的邏輯,和bloc
相比較代碼較為簡(jiǎn)潔,ChangeNotifier
繼承自Listenable
,Listenable是一個(gè)維護(hù)監(jiān)聽(tīng)者列表的對(duì)象,通過(guò)它我們可以調(diào)用notifyListeners();
方法發(fā)送通知監(jiān)聽(tīng)者實(shí)現(xiàn)頁(yè)面狀態(tài)的更新。
/// 業(yè)務(wù)邏輯層 class PNumProvider extends ChangeNotifier { /// 初始化數(shù)據(jù)對(duì)象 final state = PNumState(num: 0); /// 自增計(jì)數(shù)方法 add() { state.num++; notifyListeners(); } }
UI層: 根結(jié)點(diǎn)返回ChangeNotifierProvider
,通過(guò)它可以讓provider實(shí)例和頁(yè)面所有子節(jié)點(diǎn)進(jìn)行綁定,實(shí)現(xiàn)create
方法和builder
方法分別返回provider
和我們的頁(yè)面Widget
。 對(duì)于需要更新的組件使用Consumer<P>
包裹,當(dāng)范型里的實(shí)例調(diào)用notifyListeners
的時(shí)候, builder
返回的Widget
將得到通知,從而達(dá)到數(shù)據(jù)的更新。
/// UI層 class PNumPage extends StatelessWidget { @override Widget build(BuildContext context) { // 通過(guò)ChangeNotifierProvider將UI層和邏輯層進(jìn)行綁定 return ChangeNotifierProvider( create: (BuildContext context) => PNumProvider(), builder: (context, child) => _buildPage(context), ); } Widget _buildPage(BuildContext context) { // 獲取provider示例 final provider = context.read<PNumProvider>(); return Stack( children: [ Consumer<PNumProvider>( builder: (context, provider, child) { // builder方法回返回provider實(shí)例,和上面獲取的實(shí)例一樣 return Center(child: Text("點(diǎn)擊了${provider.state.num}次")); }, ), Positioned( child: FloatingActionButton( onPressed: () { // 調(diào)用自增方法 provider.add(); }, child: Icon(Icons.add), ), bottom: 20, right: 20, ) ], ); } }
效果:
當(dāng)然上方的代碼也可以通過(guò)小呆呆的插件自動(dòng)生成。
全局狀態(tài)
provider
全局狀態(tài)使用也非常的方便,我們剛才的邏輯層需要在頂層runApp方法里進(jìn)行初始化provider
,使用MultiProvider
可以同時(shí)管理多個(gè)全局狀態(tài)。
//全部狀態(tài)管理 class Status { // 全局初始化 static Widget init(Widget child) { //使用 MultiProvider 設(shè)置多個(gè)Provider 狀態(tài) return MultiProvider( providers: [ ChangeNotifierProvider( // 全局管理app主題 create: (_) => AppTheme(AppTheme.getDefaultTheme())), ], child: child, ); } } // 在 runApp方法之前初始化 runApp(Status.init(MyApp()));
在接收的地方還是一樣使用Consumer
包裹組件,代碼略...
總結(jié)
provider
相較于bloc
沒(méi)有強(qiáng)制的分層,即使是數(shù)據(jù)也是我們自己分出來(lái)的,不分出來(lái)直接寫(xiě)在邏輯層也是可以的,所以provider
的使用感覺(jué)更加的靈活一些。對(duì)于不同項(xiàng)目我們可以使用不同的框架,開(kāi)發(fā)人多建議bloc
強(qiáng)制代碼分層,如果人少就provider
。
以上就是Flutter狀態(tài)管理Provider的使用示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Flutter狀態(tài)管理Provider的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android實(shí)現(xiàn)整理PackageManager獲取所有安裝程序信息
這篇文章主要介紹了Android實(shí)現(xiàn)整理PackageManager獲取所有安裝程序信息的方法,實(shí)例分析了Android使用PackageManager獲取安裝程序信息的具體步驟與相關(guān)技巧,需要的朋友可以參考下2016-01-01Android studio so庫(kù)找不到問(wèn)題解決辦法
這篇文章主要介紹了Android studio so庫(kù)找不到問(wèn)題解決辦法的相關(guān)資料,希望通過(guò)本文能幫助到大家解決出現(xiàn)的這種問(wèn)題,需要的朋友可以參考下2017-10-10Android實(shí)現(xiàn)簡(jiǎn)單的下拉刷新pulltorefresh
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)簡(jiǎn)單的下拉刷新pulltorefresh的相關(guān)代碼,具有一定的實(shí)用性和操作價(jià)值,感興趣的小伙伴們可以參考一下2016-07-07如何在Android中實(shí)現(xiàn)漸顯按鈕的左右滑動(dòng)效果
本篇文章是對(duì)在Android中實(shí)現(xiàn)漸顯按鈕的左右滑動(dòng)效果進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06kotlin實(shí)現(xiàn)快遞與號(hào)碼歸屬地查詢(xún)案例詳解
時(shí)間軸時(shí)一個(gè)很炫酷的效果,一般作用在物流信息上,我們同樣也可以作為一個(gè)學(xué)習(xí)對(duì)象去學(xué)習(xí)他的使用方法,同時(shí)呢,我們可以在線(xiàn)查詢(xún)我們的電話(huà)號(hào)碼歸屬地,巧用鍵盤(pán)的邏輯提升我們用戶(hù)體驗(yàn)2023-02-02android ListView自動(dòng)滾動(dòng)方法
直接在Layout中寫(xiě)即可,注意下面的stackFromBottom以及transcriptMode這兩個(gè)屬性2013-01-01