flutter?Bloc?實(shí)現(xiàn)原理示例解析
序言
在flutter
開(kāi)發(fā)中,我們使用 bloc 框架,基于狀態(tài)變更進(jìn)行響應(yīng)式開(kāi)發(fā)。本篇文章,小轟將 bloc
核心業(yè)務(wù)塊進(jìn)行拆解簡(jiǎn)化,聊一聊它的實(shí)現(xiàn)思想,bloc 核心能力分為如下兩點(diǎn):
- 添加事件
event
,將 '事件流' 轉(zhuǎn)換為 '狀態(tài)流'state
- 監(jiān)聽(tīng)
bloc
流,每次state
狀態(tài)變更,通知widget
更新
下面,用自定義Bloc的方式,來(lái)給大家講解一下Bloc的原理構(gòu)造
1. 事件流 > 狀態(tài)流 (中轉(zhuǎn))
首先,我們將bloc
代碼簡(jiǎn)化,我們來(lái)看看bloc
如何將事件流轉(zhuǎn)換為狀態(tài)流。簡(jiǎn)化代碼如下:
import 'dart:async'; abstract class ACubit<State> { StreamController<State> _controller = StreamController<State>.broadcast(); State _state; State get state => _state; ACubit(this._state); ///發(fā)送State狀態(tài)到流里面 void emit(State state) { if (_controller.isClosed) return; if (state == _state) return; _state = state; _controller.add(_state); } ///提供方法外部監(jiān)聽(tīng)State StreamSubscription<State> listen( void Function(State state) onData, { Function onError, void Function() onDone, bool cancelOnError, }) { return _controller.stream.listen( onData, onError: onError, onDone: onDone, cancelOnError: cancelOnError, ); } Future<void> close() { return _controller.close(); } }
ACubit
提供最基礎(chǔ)的能力。提供listen
方法給外部監(jiān)聽(tīng) 'State' 變更;emit
方法用來(lái)響應(yīng)state
狀態(tài)變更。
abstract class ABloc<Event, State> extends ACubit<State> { final _eventController = StreamController<Event>.broadcast(); ABloc(State initState) : super(initState) { _bindEventToState(); } ///發(fā)送事件 void add(Event event) { if (_eventController.isClosed) return; _eventController.add(event); } ///需上層實(shí)現(xiàn) (根據(jù)event轉(zhuǎn)成state) Stream<State> mapEventToState(Event event); ///將事件流(event)轉(zhuǎn)換成狀態(tài)流(state) _bindEventToState() { _eventController.stream // asyncExpand 將流內(nèi)容進(jìn)行類型轉(zhuǎn)換,結(jié)果還是流 .asyncExpand((event) => mapEventToState(event)) .listen((nextState) { ///將nextState與當(dāng)前state進(jìn)行比對(duì),比對(duì)成功后放入流中 emit(nextState); }); } }
ABloc
是我們直接使用的基類。在構(gòu)造函數(shù)中調(diào)用了_bindEventToState
將事件流轉(zhuǎn)換為狀態(tài)流。
2. 使用 BlocBuilder 實(shí)時(shí)監(jiān)聽(tīng)狀態(tài)變更, 如何實(shí)現(xiàn)的呢?
小轟做了一個(gè)簡(jiǎn)化版的原理講解:
import 'package:flutter/material.dart'; import 'a_bloc.dart'; class BlocBuilder<T extends ACubit<S>, S> extends StatefulWidget { final T cubit; final Widget Function(BuildContext context, S state) builder; const BlocBuilder({ Key key, @required this.cubit, @required this.builder, }) : super(key: key); @override _BlocBuilderState<S> createState() => _BlocBuilderState<S>(); } class _BlocBuilderState<S> extends State<BlocBuilder> { void _update() { setState(() {}); } @override void initState() { ///監(jiān)聽(tīng)state狀態(tài)變更 widget.cubit?.listen((_) { _update(); }); super.initState(); } @override void dispose() { widget.cubit?.close(); super.dispose(); } @override Widget build(BuildContext context){ return widget.builder( context, widget.cubit.state, ); } }
封裝 BlocBuilder
- 構(gòu)造函數(shù)中傳入自定義的 bloc (繼承
ABloc
),builder
傳參用于獲取每次state
變更通知。 - 在
initState
初始化方法中對(duì)cubit
進(jìn)行狀態(tài)監(jiān)聽(tīng),每次狀態(tài)變更直接調(diào)用setState
方法進(jìn)行頁(yè)面更新
調(diào)用示例如下:
return BlocBuilder<CountBloc, CountState>( cubit: CountBloc(CountState(1)), builder: (context, state) { return Container(...省略業(yè)務(wù)代碼) }, )
總結(jié)
bloc 庫(kù)中引用了provider 等三方庫(kù)?;?code>InheritedWidget實(shí)現(xiàn)了數(shù)據(jù)共享能力。本篇文章,小轟只為演示Bloc核心的處理思想。詳細(xì)請(qǐng)查閱Bloc源碼。
擴(kuò)展
InheritedProvider 實(shí)現(xiàn)數(shù)據(jù)共享 Bloc同時(shí)add兩次只響應(yīng)一次問(wèn)題處理
以上就是flutter Bloc 實(shí)現(xiàn)原理示例解析的詳細(xì)內(nèi)容,更多關(guān)于flutter Bloc 實(shí)現(xiàn)原理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android編程雙重單選對(duì)話框布局實(shí)現(xiàn)與事件監(jiān)聽(tīng)方法示例
這篇文章主要介紹了Android編程雙重單選對(duì)話框布局實(shí)現(xiàn)與事件監(jiān)聽(tīng)方法,涉及Android雙重單選對(duì)話框的界面布局與事件監(jiān)聽(tīng)、響應(yīng)等相關(guān)操作技巧,需要的朋友可以參考下2017-10-10Android ListView彈性效果的實(shí)現(xiàn)方法
這篇文章主要為大家詳細(xì)介紹了Android ListView彈性效果的實(shí)現(xiàn)方法,感興趣的小伙伴們可以參考一下2016-05-05基于Retrofit2+RxJava2實(shí)現(xiàn)Android App自動(dòng)更新
這篇文章主要為大家詳細(xì)介紹了基于Retrofit2+RxJava2實(shí)現(xiàn)Android App自動(dòng)更新,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05淺談Android開(kāi)發(fā)系列網(wǎng)絡(luò)篇之Retrofit
這篇文章主要介紹了淺談Android開(kāi)發(fā)系列網(wǎng)絡(luò)篇之Retrofit,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2016-12-12Android Support Library 標(biāo)題欄(Toolbar)滾動(dòng)效果實(shí)現(xiàn)方法
下面小編就為大家?guī)?lái)一篇Android Support Library 標(biāo)題欄(Toolbar)滾動(dòng)效果實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-03-03Android 獲取服務(wù)器與客戶端時(shí)差的實(shí)例代碼
下面小編就為大家分享一篇Android 獲取服務(wù)器與客戶端時(shí)差的實(shí)例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-01-01Android編程滑動(dòng)效果之倒影效果實(shí)現(xiàn)方法(附demo源碼下載)
這篇文章主要介紹了Android編程滑動(dòng)效果之倒影效果實(shí)現(xiàn)方法,基于繼承BaseAdapter自定義Gallery和ImageAdapter實(shí)現(xiàn)倒影的功能,并附帶demo源碼供讀者下載參考,需要的朋友可以參考下2016-02-02Android實(shí)現(xiàn)類似iOS風(fēng)格的對(duì)話框?qū)嵗a
通過(guò)本文給大家分享一個(gè)簡(jiǎn)單的常用的對(duì)話框類,關(guān)于Android實(shí)現(xiàn)類似iOS風(fēng)格的對(duì)話框?qū)嵗a大家通過(guò)本文學(xué)習(xí)下吧2017-09-09詳解Android開(kāi)發(fā)中ContentObserver類的使用
這篇文章主要介紹了詳解Android開(kāi)發(fā)中ContentObserver類的使用,ContentObserver內(nèi)容觀察者主要用來(lái)監(jiān)聽(tīng)uri的改變請(qǐng)情況,需要的朋友可以參考下2016-04-04