Flutter狀態(tài)管理Bloc使用示例詳解
前言
目前Flutter三大主流狀態(tài)管理框架分別是provider
、flutter_bloc
、getx
,三大狀態(tài)管理框架各有優(yōu)劣,本篇文章將介紹其中的flutter_bloc
框架的使用,他是bloc
設(shè)計(jì)思想模式在flutter上的實(shí)現(xiàn),bloc
全程全稱 business logic
,業(yè)務(wù)邏輯的意思,核心思想就是最大程度的將頁面ui與數(shù)據(jù)邏輯的解耦,使我們的項(xiàng)目可讀性、可維護(hù)性、健壯性增強(qiáng)。
兩種使用模式
首先第一步引入插件:
flutter_bloc: ^8.1.1
引入之后,flutter_bloc
使用支持以下兩種模式管理。
Bloc
模式,分別有ui層(view)、數(shù)據(jù)層(state)、事件層(event)、邏輯處理層(bloc)
,適合大型復(fù)雜頁面使用。這四層結(jié)構(gòu)bloc
在源碼處就進(jìn)行了封裝處理,所以我們使用的時(shí)候是必須要分離出來的,比如event
和state
是要強(qiáng)制分開去寫的。這也導(dǎo)致了簡單頁面使用此模式復(fù)雜化的問題,所以這種模式對于簡單頁面是非常沒有必要的,但是如果是復(fù)雜頁面的話,非常建議使用此模式,相信你在處理頁面數(shù)據(jù)邏輯的時(shí)候會(huì)非常的清晰。
下面我們以計(jì)數(shù)器為例寫個(gè)demo,記住bloc
模式有四層,且必須分開,我們建四個(gè)文件分別代表這四層,
數(shù)據(jù)層: 用來存放數(shù)據(jù),這個(gè)很簡單。
/// 數(shù)據(jù)層 class DemoState { // 自增數(shù)字 late int num; DemoState init() { // 初始化為0 return DemoState()..num = 0; } DemoState clone() { // 獲取最新對象 return DemoState()..num = num; } }
事件層: 用來存放頁面所有事件的地方,比如計(jì)數(shù)器頁面只有初始化事件和自增事件。
/// 頁面中所有的交互事件 abstract class DemoEvent {} /// 初始化事件 class InitEvent extends DemoEvent {} /// 自增事件 class IncrementEvent extends DemoEvent {}
Bloc邏輯處理層: 處理上方數(shù)據(jù)和事件邏輯的地方,通過源碼就能發(fā)現(xiàn)作者的意圖,泛型里必須分開傳入事件和數(shù)據(jù),也足以說明這個(gè)模式的特點(diǎn),就是為復(fù)雜頁面準(zhǔn)備的。
所以如果寫計(jì)數(shù)器的話,你就會(huì)感覺非常沒有必要,因?yàn)橛?jì)數(shù)器頁面很簡單,但是當(dāng)你的state
層里的數(shù)據(jù)非常多且復(fù)雜的時(shí)候,你就能體會(huì)出分開的好處了。
代碼:
/// 邏輯處理層 繼承Bloc class DemoBloc extends Bloc<DemoEvent, DemoState> { ///構(gòu)造方法 DemoBloc() : super(DemoState().init()) { /// on 注冊所有事件 on固定寫法 on<InitEvent>(_init); on<IncrementEvent>(_add); } /// 私有化邏輯方法 暴露Event事件即可 void _init(InitEvent event, Emitter<DemoState> emit) { // emit方法,通知更新狀態(tài) 類似于 ChangeNotifier的notifyListeners方法。 emit(state.clone()); } _add(IncrementEvent event, Emitter<DemoState> emit) { state.num++; // 調(diào)用emit方法更新狀態(tài) emit(state.clone()); } }
UI層: UI層只負(fù)責(zé)頁面的編寫,而無需關(guān)心數(shù)據(jù)的生成,根節(jié)點(diǎn)返回BlocProvider
,并實(shí)現(xiàn)create
方法,返回我們的bloc實(shí)體類。child
實(shí)現(xiàn)我們的 UI頁面。
/// UI層 class BlocNumPage extends StatelessWidget { @override Widget build(BuildContext context) { // 以下固定寫法 return BlocProvider( create: (BuildContext context) => DemoBloc()..add(InitEvent()), child: Builder(builder: (context) => _buildPage(context)), ); } Widget _buildPage(BuildContext context) { // 獲取bloc實(shí)例 final bloc = BlocProvider.of<DemoBloc>(context); return Stack( children: [ Center( // 對于需要更新狀態(tài)的組件 外層包裹一個(gè)BlocBuilder,傳入bloc、state child: BlocBuilder<DemoBloc, DemoState>( builder: (context, state) { // 返回具體ui組件 return Text("點(diǎn)擊了${bloc.state.num}次"); }, ), ), Positioned( bottom: 20, right: 20, child: FloatingActionButton( onPressed: () { // 調(diào)用add方法觸發(fā)自增事件, bloc.add(IncrementEvent()); }, child: Icon(Icons.add), ), ) ], ); } }
效果:
Cubit模式
Cubit
模式,分別有ui層(view)、數(shù)據(jù)層(state)、邏輯處理層(cubit)
,相較于bloc
模式去掉了event層,適合比較簡單的頁面。跟bloc
模式只是邏輯處理哪里發(fā)生了改變,數(shù)據(jù)層、頁面ui層代碼一模一樣。
可以看到Cubit
模式的邏輯就少了很多代碼,而且是直接處理數(shù)據(jù)即可。通過源碼,作者意圖也很明顯,只是傳遞了數(shù)據(jù)層。
/// 寫邏輯 class CubitCubit extends Cubit<CubitState> { CubitCubit() : super(CubitState().init()); ///自增 void increment() => emit(state.clone()..num = state.num + 1); }
其他寫法跟Bloc
是一樣的,就不粘貼了,那看到這有的小伙伴可能就要問了,一個(gè)頁面要?jiǎng)?chuàng)建3、4個(gè)文件,這也太麻煩了吧,高端的程序員往往不會(huì)去寫一些重復(fù)性較高的代碼,其實(shí)上面的四個(gè)文件都是可以通過插件自動(dòng)生成的,這里下面兩個(gè)插件,一個(gè)是官方的,官方的不會(huì)自動(dòng)生成ui層的文件,一個(gè)是小呆呆寫的,可以自動(dòng)生成ui層重復(fù)性的代碼文件,兩者區(qū)別不大,推薦小呆呆的,因?yàn)榭梢远嗌梢粋€(gè)文件。
最后
Bloc本質(zhì)上是一種數(shù)據(jù)邏輯和UI解耦思想,上面的演示只是非常非常簡單的用法,就可以看出作者在源碼層給我們強(qiáng)制性的設(shè)定了非常明確的各個(gè)模型,每個(gè)模型只專心負(fù)責(zé)一個(gè)事情,這樣看起來一個(gè)頁面會(huì)非常的清晰,可以說Flutter_Bloc
是一個(gè)非常適合大型項(xiàng)目使用的狀態(tài)管理框架。
以上就是Flutter狀態(tài)管理Bloc使用示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Flutter狀態(tài)管理Bloc的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android使用SoundPool實(shí)現(xiàn)播放音效
這篇文章主要為大家詳細(xì)介紹了Android使用SoundPool實(shí)現(xiàn)播放音效,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11Android實(shí)現(xiàn)可拖拽帶有坐標(biāo)尺進(jìn)度條的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用Android實(shí)現(xiàn)可拖拽帶有坐標(biāo)尺進(jìn)度條的效果,文中的示例代碼講解詳細(xì),需要的小伙伴可以參考一下2023-06-06Android開發(fā)手冊Chip監(jiān)聽及ChipGroup監(jiān)聽
這篇文章主要為大家介紹了Android開發(fā)手冊Chip監(jiān)聽及ChipGroup監(jiān)聽,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06使用Timer實(shí)現(xiàn)網(wǎng)頁勻速加載的進(jìn)度條樣式
這篇文章主要介紹了使用Timer實(shí)現(xiàn)網(wǎng)頁勻速加載的進(jìn)度條樣式,在使用WebView加載網(wǎng)頁時(shí)有時(shí)候網(wǎng)速等原因加載比較慢時(shí),影響用戶的體驗(yàn)度,今天小編給大家分享使用timer實(shí)現(xiàn)網(wǎng)頁勻速加載的進(jìn)度條樣式,需要的的朋友參考下吧2017-01-01Android permission denied原因歸納和解決辦法
大家好,本篇文章主要講的是Android permission denied原因歸納和解決辦法,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下哦2021-12-12PC版與Android手機(jī)版帶斷點(diǎn)續(xù)傳的多線程下載
這篇文章主要介紹了PC版與Android手機(jī)版帶斷點(diǎn)續(xù)傳的多線程下載的相關(guān)資料,需要的朋友可以參考下2015-10-10學(xué)習(xí)使用Android Chronometer計(jì)時(shí)器
Chronometer是一個(gè)簡單的計(jì)時(shí)器,你可以給它一個(gè)開始時(shí)間,并以計(jì)時(shí),或者如果你不給它一個(gè)開始時(shí)間,它將會(huì)使用你的時(shí)間通話開始,這篇文章主要幫助大家學(xué)習(xí)掌握使用Android Chronometer計(jì)時(shí)器,感興趣的小伙伴們可以參考一下2016-04-04Android截取指定View為圖片的實(shí)現(xiàn)方法
這篇文章主要為大家詳細(xì)介紹了Android截取指定View為圖片的實(shí)現(xiàn)方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-06-06Android仿微信聯(lián)系人列表字母側(cè)滑控件
這篇文章主要為大家詳細(xì)介紹了Android仿微信聯(lián)系人列表字母側(cè)滑控件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06