
Flutter BLoC.jpg
BLoC其实就是在Provider的基础上,增加了一个事件流。让我们可以实现类似于MVVM的代码架构。BLoC的主要的代码结构分为四个部分,Widget、Bloc、State、Event
Widget
负责两件事情,第一件,将界面的所有的用户操作转化为Event发送给Bloc。第二件,监听Bloc的State,并根据State更新界面。MVVM中的View
Bloc
负责两件事情,第一件,监听Widget发送过来的Event,根据Event获取对应的数据并转化为State。第二件,把State发送给Widget。MVVM中的ViewModel
State
可以是任意类型,负责存储widget界面所需的数据。MVVM中的Model
Event
可以是任意类型
下面是使用BLoC项目中BaseWidget的封装
一共三个类BaseWidget、BaseBlocWidget、BaseCubitWidget。前面说到BLoC其实就是基于Provider的,所以BLoC其实保留了Provider的用法,就是Cubit,所以我这里封装了两个用法,BaseBlocWidget就是Bloc的事件流用法,BaseCubitWidget就是Provider的用法
BaseWidget
abstract class BaseWidget extends StatefulWidget {
const BaseWidget({super.key});
}
abstract class BaseWidgetState<T extends BaseWidget, B extends BlocBase<S>, S>
extends State<T> {
@override
Widget build(context) {
//page根部创建BlocProvider
return BlocProvider<B>(
key: widget.key,
create: (context) {
return createBlocOrCubit();
},
child: BlocListener<B, S>(
key: widget.key,
listenWhen: blocListenerWhen,
listener: blocListener,
child: BlocBuilder<B, S>(
buildWhen: blocBuildWhen,
builder: (context, state) {
return blocBuild(context, state) ;
},
),
));
}
///返回false时,[Bloc.emit]/[Cubit.emit]不会触发[blocListener]调用
///用于控制非必要刷新
bool blocListenerWhen(S previous, S current) => true;
///[Bloc.emit]/[Cubit.emit]调用时并且[blocListenerWhen]为true会触发此方法调用
blocListener(BuildContext context, S state);
///返回false时,[Bloc.emit]/[Cubit.emit]不会触发[blocBuild]调用
///用于控制非必要刷新
bool blocBuildWhen(S previous, S current) => true;
///[build]方法调用时会触发此方法
///[Bloc.emit]/[Cubit.emit]调用时并且[blocBuildWhen]为true会触发此方法调用
///返回null则显示[emptyWidget]
Widget blocBuild(BuildContext context, S state);
///创建bloc/cubit
B createBlocOrCubit();
///从context中获取bloc
B readBlocOrCubit(BuildContext context) => context.read<B>();
}
BaseBlocWidget
abstract class BaseBlocWidget extends BaseWidget {
const BaseBlocWidget({super.key});
}
///[T] widget类型
///[B] Bloc类型
///[E] Event类型
///[S] State类型
abstract class BaseBlocWidgetState<T extends BaseBlocWidget,
B extends Bloc<E, S>, E, S> extends BaseWidgetState<T, B, S> {}
BaseCubitWidget
abstract class BaseCubitWidget extends BaseWidget {
const BaseCubitWidget({super.key});
}
///[T] widget类型
///[C] Cubit类型
///[S] State类型
abstract class BaseCubitWidgetState<T extends BaseCubitWidget,
C extends Cubit<S>, S> extends BaseWidgetState<T, C, S> {}
继承BaseBlocWidget使用
///event
sealed class DemoPage1Event {}
///state
class DemoPage1State {}
///bloc
class DemoPage1Bloc extends Bloc<DemoPage1Event, DemoPage1State> {
DemoPage1Bloc() : super(DemoPage1State());
}
class DemoPage1 extends BaseBlocWidget {
const DemoPage1({super.key});
@override
State<DemoPage1> createState() => _DemoPage1State();
}
class _DemoPage1State extends BaseBlocWidgetState<DemoPage1,DemoPage1Bloc,DemoPage1Event,DemoPage1State> {
@override
Widget blocBuild(BuildContext context, DemoPage1State state) {
return Container();
}
@override
blocListener(BuildContext context, DemoPage1State state) {
}
@override
DemoPage1Bloc createBlocOrCubit() {
return DemoPage1Bloc();
}
}
继承BaseCubitWidget使用
///state
class DemoPage2State {}
///cubit
class DemoPage2Cubit extends Cubit<DemoPage2State> {
DemoPage2Cubit() : super(DemoPage2State());
}
class DemoPage2 extends BaseCubitWidget {
const DemoPage2({super.key});
@override
State<DemoPage2> createState() => _DemoPage2State();
}
class _DemoPage2State extends BaseCubitWidgetState<DemoPage2,DemoPage2Cubit,DemoPage2State> {
@override
Widget blocBuild(BuildContext context, DemoPage2State state) {
return Container();
}
@override
blocListener(BuildContext context, DemoPage2State state) {
}
@override
DemoPage2Cubit createBlocOrCubit() {
return DemoPage2Cubit();
}
}