Flutter状态管理Bloc使用示例详解
作者:老李code 发布时间:2023-08-24 09:09:10
前言
目前Flutter三大主流状态管理框架分别是provider
、flutter_bloc
、getx
,三大状态管理框架各有优劣,本篇文章将介绍其中的flutter_bloc
框架的使用,他是bloc
设计思想模式在flutter上的实现,bloc
全程全称 business logic
,业务逻辑的意思,核心思想就是最大程度的将页面ui与数据逻辑的解耦,使我们的项目可读性、可维护性、健壮性增强。
两种使用模式
首先第一步引入插件:
flutter_bloc: ^8.1.1
引入之后,flutter_bloc
使用支持以下两种模式管理。
Bloc
模式,分别有ui层(view)、数据层(state)、事件层(event)、逻辑处理层(bloc)
,适合大型复杂页面使用。这四层结构bloc
在源码处就进行了封装处理,所以我们使用的时候是必须要分离出来的,比如event
和state
是要强制分开去写的。这也导致了简单页面使用此模式复杂化的问题,所以这种模式对于简单页面是非常没有必要的,但是如果是复杂页面的话,非常建议使用此模式,相信你在处理页面数据逻辑的时候会非常的清晰。
下面我们以计数器为例写个demo,记住bloc
模式有四层,且必须分开,我们建四个文件分别代表这四层,
数据层: 用来存放数据,这个很简单。
/// 数据层
class DemoState {
// 自增数字
late int num;
DemoState init() {
// 初始化为0
return DemoState()..num = 0;
}
DemoState clone() {
// 获取最新对象
return DemoState()..num = num;
}
}
事件层: 用来存放页面所有事件的地方,比如计数器页面只有初始化事件和自增事件。
/// 页面中所有的交互事件
abstract class DemoEvent {}
/// 初始化事件
class InitEvent extends DemoEvent {}
/// 自增事件
class IncrementEvent extends DemoEvent {}
Bloc逻辑处理层: 处理上方数据和事件逻辑的地方,通过源码就能发现作者的意图,泛型里必须分开传入事件和数据,也足以说明这个模式的特点,就是为复杂页面准备的。
所以如果写计数器的话,你就会感觉非常没有必要,因为计数器页面很简单,但是当你的state
层里的数据非常多且复杂的时候,你就能体会出分开的好处了。
代码:
/// 逻辑处理层 继承Bloc
class DemoBloc extends Bloc<DemoEvent, DemoState> {
///构造方法
DemoBloc() : super(DemoState().init()) {
/// on 注册所有事件 on固定写法
on<InitEvent>(_init);
on<IncrementEvent>(_add);
}
/// 私有化逻辑方法 暴露Event事件即可
void _init(InitEvent event, Emitter<DemoState> emit) {
// emit方法,通知更新状态 类似于 ChangeNotifier的notifyListeners方法。
emit(state.clone());
}
_add(IncrementEvent event, Emitter<DemoState> emit) {
state.num++;
// 调用emit方法更新状态
emit(state.clone());
}
}
UI层: UI层只负责页面的编写,而无需关心数据的生成,根节点返回BlocProvider
,并实现create
方法,返回我们的bloc实体类。child
实现我们的 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实例
final bloc = BlocProvider.of<DemoBloc>(context);
return Stack(
children: [
Center(
// 对于需要更新状态的组件 外层包裹一个BlocBuilder,传入bloc、state
child: BlocBuilder<DemoBloc, DemoState>(
builder: (context, state) {
// 返回具体ui组件
return Text("点击了${bloc.state.num}次");
},
),
),
Positioned(
bottom: 20,
right: 20,
child: FloatingActionButton(
onPressed: () {
// 调用add方法触发自增事件,
bloc.add(IncrementEvent());
},
child: Icon(Icons.add),
),
)
],
);
}
}
效果:
Cubit模式
Cubit
模式,分别有ui层(view)、数据层(state)、逻辑处理层(cubit)
,相较于bloc
模式去掉了event层,适合比较简单的页面。跟bloc
模式只是逻辑处理哪里发生了改变,数据层、页面ui层代码一模一样。
可以看到Cubit
模式的逻辑就少了很多代码,而且是直接处理数据即可。通过源码,作者意图也很明显,只是传递了数据层。
/// 写逻辑
class CubitCubit extends Cubit<CubitState> {
CubitCubit() : super(CubitState().init());
///自增
void increment() => emit(state.clone()..num = state.num + 1);
}
其他写法跟Bloc
是一样的,就不粘贴了,那看到这有的小伙伴可能就要问了,一个页面要创建3、4个文件,这也太麻烦了吧,高端的程序员往往不会去写一些重复性较高的代码,其实上面的四个文件都是可以通过插件自动生成的,这里下面两个插件,一个是官方的,官方的不会自动生成ui层的文件,一个是小呆呆写的,可以自动生成ui层重复性的代码文件,两者区别不大,推荐小呆呆的,因为可以多生成一个文件。
最后
Bloc本质上是一种数据逻辑和UI解耦思想,上面的演示只是非常非常简单的用法,就可以看出作者在源码层给我们强制性的设定了非常明确的各个模型,每个模型只专心负责一个事情,这样看起来一个页面会非常的清晰,可以说Flutter_Bloc
是一个非常适合大型项目使用的状态管理框架。
来源:https://juejin.cn/post/7160259367563067400
猜你喜欢
- 一.HashMap 和Hashtable 的区别我们先看2个类的定义 public class Hashtable exten
- 简单的实现了一个树的结构,很不完善!后续参考一些其他代码的实现。试图实现叶子存在可变的节点,能够用来解析xml文件。叶子的代码:packag
- 我们还是用一个小例子来看看自定义View和自定义属性的使用,带大家来自己定义一个带进度的圆形进度条,我们还是先看一下效果吧从上面可以看出,我
- 什么是异步?为什么要用它?异步编程提供了一个非阻塞的,事件驱动的编程模型。 这种编程模型利用系统中多核执行任务来提供并行,因此提供了应用的吞
- 消息都是存放在一个消息队列中去,而消息循环线程就是围绕这个消息队列进入一个无限循环的,直到线程退出。如果队列中有消息,消息循环线程就会把它取
- 本文实例讲述了C#创建临时文件的方法。分享给大家供大家参考。具体分析如下:C#可以通过Path.GetTempFileName获得一个临时文
- Java中List.of()和Arrays.asList()的区别及原因动手写一下,让自己更有印象1.Arrays.asList()可以插入
- 记录一下微信第三方实现登录的方法。还是比较简单。一、必要的准备工作1.首先需要注册并被审核通过的微信开放平台帐号,然后创建一个移动应用,也需
- FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化
- 前言很多时候,当你以为掌握了事实真相的时间,如果你能再深入一点,你可能会发现另外一些真相。比如面向切面编程的最佳编程实践是AOP,AOP的主
- 一、导入和导出导入:通过解析excel表格中的数据,然后将数据放到一个集合中,接着通过对持久层操作,将数据插入到数据库中,再加载一下页面,从
- 什么是OKHttp一般在Java平台上,我们会使用Apache HttpClient作为Http客户端,用于发送 HTTP 请求,并对响应进
- 一个错误:多线程使用单一消费者下图显现了一种错误的使用KafkaConsumer的方法创建多个线程用来消费kafka数据多线程使用同一个Ka
- 前几天在跟公司大佬讨论一个问题时,看到他使用Handler的一种方式,旁边的同事在说:以前不是这么用的啊。这个问题引发了我的好奇,虽然当时翻
- 一、Jvm加载对象在说Java * 之前,还是要说一下Jvm加载对象的过程,这个依旧是理解 * 的基础性原理:Java类即源代码程序.j
- 前言我们在学习Windows应用程序开发中,经常会用到消息对话框给用户或者管理员一些的消息提示,它们都是基于对MessageBox类的消息对
- 由于我们在eclipse ee中把项目部署在web端经常会出现报404错误。原因为:404状态码是一种http状态码,其意思是: 所请求的页
- Feign的作用是将Http请求抽象化为一个Interface客户端,可以调用接口的形式来执行Http请求,以达到简化Http调用的目的。F
- 1.最常用的方法是创建一个计数器,判断是否遇到‘\0',不是'\0'指针就往后加一。int my_strlen(co
- 在使用springMVC框架构建web应用,客户端常会请求字符串、整型、json等格式的数据,通常使用@ResponseBody注解使 co