写点什么

【Flutter 专题】86 初识状态管理 Bloc (一)

发布于: 2 小时前
【Flutter 专题】86 初识状态管理 Bloc (一)

      小菜以前尝试过 provider 状态管理工具,简单便捷;但在新的项目中,相关同学采用的是 Bloc 状态管理工具,且前段时间何时简单了解了 Stream 相关知识,因此趁机学习一下基本的 Bloc 相关的内容;

Bloc

      Bloc 可以方便的把样式与业务逻辑区分开,从而使开发更便捷,可重用性更好,测试也更加方便;



      在使用 Bloc 之前需要提前了解一下如下几个概念;

Event

      Event 事件作为 Bloc 的输入,一般是为了响应用户交互(例如按钮按下)或生命周期事件(例如页面加载)而添加它们。可以使用枚举类型定义事件类,对于相对复杂的事件可以联合业务定义为 class


enum TestEvent { onEvent1, onEvent2 ... onEventN}
复制代码

States

      States 状态作为 Bloc 的输出,一般用于 UI 状态的更新,页面更新绘制等;一般需要定义不同的数据类型来表示数据状态的变更;


class TestState {    final int state1;    final String state2;    ...    final User stateN;        TestState(this.state1, this.state2 ... this.stateN);}
复制代码

Transitions

      Transitions 转场作为从一个状态到下一个状态的过度,过渡由当前状态,事件和下一个状态组成;例如小菜上述定义的 TestEvent 中的各个 onEvent 中状态变更等均可以视为 Transitions 转场;onTransitionBlocstate 更新之前被调用,常用于记录 Bloc 日志和分析;


@overridevoid onTransition(Transition<NumberEvent, int> transition) {  print('====onTransition===${transition}');  super.onTransition(transition);}
复制代码

Streams

      作为异步数据传输;其中使用 async* 时可以使用 yield 关键字并返回一个 Stream 数据;


Stream<int> testStream(int max) async* {    for (int i = 0; i < max; i++) {        yield i;    }}
复制代码

Blocs

      Bloc 作为将 Stream 输入的 Event 事件转换为输出的 States 状态;每个自定义的 Bloc 必须继承自基础的 Bloc;通过复写 initialStatemapEventToState 方法来完成事件 EventState 状态的转换;      initialStateBloc 初始化状态,该状态是接收任何事件之前的状态;      mapEventToStateEvent 作为参数,返回的是 Streamstate 状态,通过 state 属性随时访问当前的块状态;      每个 Bloc 都有一个 add 方法,用来添加新的 EventmapEventToState 中;      Bloc 通过 onError 方法获取异常信息并处理等;


class TestBloc extends Bloc<TestEvent, int> {  @override  int get initialState => 0;
@override Stream<int> mapEventToState(TestEvent event) async* { switch (event) { case TestEvent.onEvent1: yield state - 1; break; case TestEvent.onEvent2: yield state + 1; break; } } @override void onError(Object error, StackTrace stackTrace) { print('====onError===$error, $stackTrace'); super.onError(error, stackTrace); }}
复制代码


BlocDelegate

      BlocDelegateBloc 的委托,可以在全局或需要的作用域范围内统一管理 onTransitiononError 等;


class NumberBlocDelegate extends BlocDelegate {  @override  void onEvent(Bloc bloc, Object event) {    print('====Delegate.onEvent===$bloc====$event');    super.onEvent(bloc, event);  }
@override void onTransition(Bloc bloc, Transition transition) { print('====Delegate.onTransition===$bloc====$transition'); super.onTransition(bloc, transition); }
@override void onError(Bloc bloc, Object error, StackTrace stackTrace) { print('====Delegate.onError===$error, $stackTrace'); super.onError(bloc, error, stackTrace); }}
复制代码


TestCode

      小菜尝试了最简单的 Bloc,点击按钮会数字会递增,目前更新 UI 是通过 setState() 方式更新数据,在下一节中会尝试用 FlutterBloc 方式进行数据更新;


import 'package:bloc/bloc.dart';import 'package:flutter/material.dart';
class BlocPage extends StatefulWidget { @override State<StatefulWidget> createState() => _BlocPageState();}
class _BlocPageState extends State<BlocPage> { var _number = 0; NumberBloc _bloc = NumberBloc();
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Bloc Page')), body: Center( child: Text('当前 Number = $_number\n下次 Number = ${_bloc.state}', style: TextStyle(fontSize: 20.0, color: Colors.blue))), floatingActionButton: FloatingActionButton( child: Icon(Icons.add), onPressed: () { _bloc.add(NumberEvent.addEvent); setState(() => _number = _bloc.state); })); }}
enum NumberEvent { addEvent }
class NumberBloc extends Bloc<NumberEvent, int> { @override int get initialState => 10;
@override Stream<int> mapEventToState(NumberEvent event) async* { switch (event) { case NumberEvent.addEvent: yield state + 5; break; } }
@override void onTransition(Transition<NumberEvent, int> transition) { print('====onTransition===${transition}'); super.onTransition(transition); }
@override void onError(Object error, StackTrace stackTrace) { print('====onError===$error, $stackTrace'); super.onError(error, stackTrace); }}
复制代码





      小菜初步体验了 Bloc,初步感觉比 Provider 稍微复杂一些,但是分工更为明确;而小菜对 Bloc 的 应用还不够熟练,下一节重点尝试 FlutterBloc 对于 UI 的数据更新等;如有错误,请多多指导!


来源: 阿策小和尚

发布于: 2 小时前阅读数: 2
用户头像

还未添加个人签名 2021.05.13 加入

Android / Flutter 小菜鸟~

评论

发布
暂无评论
【Flutter 专题】86 初识状态管理 Bloc (一)