網站首頁 編程語言 正文
序言
在flutter
開發中,我們使用 bloc 框架,基于狀態變更進行響應式開發。本篇文章,小轟將 bloc
核心業務塊進行拆解簡化,聊一聊它的實現思想,bloc 核心能力分為如下兩點:
- 添加事件
event
,將 '事件流' 轉換為 '狀態流'state
- 監聽
bloc
流,每次state
狀態變更,通知widget
更新
下面,用自定義Bloc的方式,來給大家講解一下Bloc的原理構造
1. 事件流 > 狀態流 (中轉)
首先,我們將bloc
代碼簡化,我們來看看bloc
如何將事件流轉換為狀態流。簡化代碼如下:
import 'dart:async'; abstract class ACubit<State> { StreamController<State> _controller = StreamController<State>.broadcast(); State _state; State get state => _state; ACubit(this._state); ///發送State狀態到流里面 void emit(State state) { if (_controller.isClosed) return; if (state == _state) return; _state = state; _controller.add(_state); } ///提供方法外部監聽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
提供最基礎的能力。提供listen
方法給外部監聽 'State' 變更;emit
方法用來響應state
狀態變更。
abstract class ABloc<Event, State> extends ACubit<State> { final _eventController = StreamController<Event>.broadcast(); ABloc(State initState) : super(initState) { _bindEventToState(); } ///發送事件 void add(Event event) { if (_eventController.isClosed) return; _eventController.add(event); } ///需上層實現 (根據event轉成state) Stream<State> mapEventToState(Event event); ///將事件流(event)轉換成狀態流(state) _bindEventToState() { _eventController.stream // asyncExpand 將流內容進行類型轉換,結果還是流 .asyncExpand((event) => mapEventToState(event)) .listen((nextState) { ///將nextState與當前state進行比對,比對成功后放入流中 emit(nextState); }); } }
ABloc
是我們直接使用的基類。在構造函數中調用了_bindEventToState
將事件流轉換為狀態流。
2. 使用 BlocBuilder 實時監聽狀態變更, 如何實現的呢?
小轟做了一個簡化版的原理講解:
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() { ///監聽state狀態變更 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
- 構造函數中傳入自定義的 bloc (繼承
ABloc
),builder
傳參用于獲取每次state
變更通知。 - 在
initState
初始化方法中對cubit
進行狀態監聽,每次狀態變更直接調用setState
方法進行頁面更新
調用示例如下:
return BlocBuilder<CountBloc, CountState>( cubit: CountBloc(CountState(1)), builder: (context, state) { return Container(...省略業務代碼) }, )
總結
bloc 庫中引用了provider 等三方庫。基于InheritedWidget
實現了數據共享能力。本篇文章,小轟只為演示Bloc核心的處理思想。詳細請查閱Bloc源碼。
擴展
InheritedProvider 實現數據共享 Bloc同時add兩次只響應一次問題處理
原文鏈接:https://juejin.cn/post/7007683747512320014
相關推薦
- 2022-11-14 解決“您的連接不是私密鏈接”的問題
- 2022-05-11 React中的Refs屬性你來了解嗎_React
- 2022-10-16 Python?結構化字符串中提取數據詳情_python
- 2022-05-25 Shell腳本獲取jar包pid進行重啟、停止、啟動
- 2022-06-22 C語言樹與二叉樹基礎全刨析_C 語言
- 2022-11-06 關于useEffect執行兩次的問題及解決_React
- 2022-06-28 深入解析docker文件分層原理_docker
- 2024-03-04 layui tree組件實現搜索節點并展開
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支