当前位置:网站首页>Bloc入门之Cubit详解
Bloc入门之Cubit详解
2022-06-26 00:51:00 【武器大师72】
背景
前面学写了一些基础的Flutter
开发知识,但是对于项目的整体架构以及开发模式并没有进行一个系统的学习,经过上网查询,发现目前很多项目采用了Bloc(业务该逻辑组件)这种开发模式,下面就找到了该库的官网
优点
Bloc可以比较轻松地将展示层的代码与业务逻辑分开,从而使您的代码快速,易于测试且可重复使用
动手
首先对于Stream
熟悉的同学可以忽略此部分,Java8
的新特性里面也有流这部分内容。
从零开始
- 从0开始,写个简单的程序认识一下
Stream
这个类新建一个文件夹:
blocTest
- 新建一个
test.dart
文件,输入以下内容,简单了解以下流这个类型 :
// 返回一个流,流里面是不大于max的数,要注意,每次yield的时候,都会向流里面推数据
Stream<int> countStream(int max) async* {
for (int i = 0; i < max; i++) {
yield i;
}
}
// 使用await等待流中的每个数据,然后返回和,而且是`Future`类型
Future<int> sumStream(Stream<int> stream) async {
int sum = 0;
await for (int value in stream) {
sum += value;
}
return sum;
}
void main() async {
Stream<int> stream = countStream(10);
int sum = await sumStream(stream);
print(sum); // 45
}
- 预热以后,开始上手,安装库
在根文件夹里面新建一个文件pubspec.yaml并输入以下内容
name: blocTest
environment:
sdk: ">=2.17.0-0 <3.0.0"
dependencies:
bloc: ^8.0.0
执行dart pub get
下载库
PS C:\Users\XXX\Desktop\blocTest> dart pub get
Resolving dependencies...
Got dependencies!
开始上手
这是偷来官网的图:
状态是从 Cubit 中输出的,代表应用程序状态的一部分。可以通知 UI 组件状态,并根据当前状态重绘其自身的某些部分。
- 创建一个Cubit 类型
// 定义了要管理的状态类型,此处以int示例,复杂业务可以自定义类
class CounterCubit extends Cubit<int> {
//CounterCubit() : super(0);//指定初始状态为0
//也可以外部传入初始值:
CounterCubit(int initialState) : super(initialState);
}
- 定义一个CounterCubit
final cubitA = CounterCubit(0); // state starts at 0
final cubitB = CounterCubit(10); // state starts at 10
- 添加输出状态的能力
class CounterCubit extends Cubit<int> {
CounterCubit() : super(0);
void increment() => emit(state + 1);
//emit只能在 Cubit 内部使用。state是当前状态
}
- 使用
import 'package:bloc/bloc.dart';
void main() {
final cubit = CounterCubit();
print(cubit.state); // 0
cubit.increment();
print(cubit.state); // 1
cubit.close();
}
- 订阅
实际上Cubit
是 Stream
的一种特殊类型,可以通过订阅来更新其状态
void myPrint(int data) {
print(data);
}
Future<void> main() async {
final cubit = CounterCubit();
final subscription = cubit.stream.listen(myPrint); // 1
cubit.increment(); //输出1
await Future.delayed(Duration.zero);
cubit.increment();//输出2
await Future.delayed(Duration.zero);
await subscription.cancel();
await cubit.close();
}
- 观察
可以通过添加onChange
函数来观察Cubit
的变化
class CounterCubit extends Cubit<int> {
CounterCubit() : super(0);
void increment() => emit(state + 1);
@override
void onChange(Change<int> change) {
super.onChange(change);
print(change);
}
}
修改main函数:
void main() {
CounterCubit()
..increment()
..increment()
..close();
}
输出结果:
Change {
currentState: 0, nextState: 1 }
Change {
currentState: 1, nextState: 2 }
可见输出了当前状态和下一次状态
- 使用BlocObserver
添加一个一个Observer:
class SimpleBlocObserver extends BlocObserver {
@override
void onChange(BlocBase bloc, Change change) {
super.onChange(bloc, change);
print('${
bloc.runtimeType} $change');
print(bloc.state);//访问Cuit实例状态
}
}
修改main函数:
void main() {
BlocOverrides.runZoned(
() {
CounterCubit()
..increment()
..close();
},
blocObserver: SimpleBlocObserver(),
);
}
上面的代码在调用CounterCubit.increment()
后会依次调用CounterCubit
本身的onChange
和SimpleBlocObserver
的onChange
,其实在BlocObserver 中也可以访问Cubit
实例(bloc变量)
- 错误处理
再次修改代码,人为在在increment()
函数里面调用addError
制造错误,此时会调用Cubit
的onError
方法进行错误处理
class CounterCubit extends Cubit<int> {
CounterCubit() : super(0);
void increment() {
addError(Exception('increment error!'), StackTrace.current);
emit(state + 1);
}
@override
void onChange(Change<int> change) {
super.onChange(change);
print(change);
}
@override
void onError(Object error, StackTrace stackTrace) {
print('$error, $stackTrace');
super.onError(error, stackTrace);
}
}
此时运行的话就会报错了
边栏推荐
- -- EGFR FISH probe solution
- Codecraft-17 and Codeforces Round #391 (Div. 1 + Div. 2, combined) D. Felicity‘s Big Secret Revealed
- Fastadmin applet assistant is purchased, but the work order cannot be published in the problem work order
- Output Lua print to the cocos2d console output window
- Tab switch
- cv==biaoding---open----cv001
- @Query difficult and miscellaneous diseases
- Back to top case
- Shell learning record (I)
- Record a weird picture upload problem
猜你喜欢
Pointnet/pointnet++ learning
接口测试用例设计
基於鄰接矩陣的廣度優先遍曆
One year's work
V4l2+qt video optimization strategy
regular expression
Largeur d'abord traversée basée sur la matrice de contiguïté
win32
One minute to understand the difference between synchronous, asynchronous, blocking and non blocking
Disruptor (I) sequence
随机推荐
Exploring temporary information for dynamic network embedding
Codecraft-17 and Codeforces Round #391 (Div. 1 + Div. 2, combined) D. Felicity‘s Big Secret Revealed
WPF 窗口居中 & 变更触发机制
SDRAM Controller - add read / write FIFO
Data analysis - data source, field type, data collection trap
Keda 2.7.1 brief analysis of scaledjob code
云答题不显示第三方登陆按钮是什么情况
shell学习记录(一)
Other codes,, VT,,, K
Fastadmin applet assistant is purchased, but the work order cannot be published in the problem work order
Shell learning record (II)
Cross server SQL connection configuration
Ndk20b ffmpeg4.2.2 compilation and integration
ROS2+DDS+RTPS
@Query 疑难杂症
跨平台应用开发进阶(二十三) :一文走近 testflight 上架
Use of static library and dynamic library
基于邻接矩阵的广度优先遍历
图的广度优先遍历
Record a weird picture upload problem