今天重点讲一下bloc ,百度一下 有关这方面的知识比较少,毕竟flutter刚刚出来半年多,我的项目里管理方式是用bloc的,也有其它的管理方式,主要看个人理解以及喜好,bloc 可以本地管理和全局管理,加上能数据UI隔离,方便后期维护,是一个不错的选择
flutter_bloc 是一个bloc第三方库,这个库很方便的让你集成bloc模式,这个库结合了RXDart,先了解一下bloc 的模式吧
1,widget 触发event 事件
2,bloc 接收event 事件并作出逻辑处理
3 ,并把逻辑处理结果给返回出来
4,UI展示数据
其实它有点像mvvm ,Event只是出发事件,并不能传值,bloc 接收这个event,根据event去找到具体的方法去处理逻辑,之后把结果返回,如果再不明白,我举个例子,我去饭店吃饭去告诉老板点一个大盘鸡(这个是event),老板根据菜名找到具体的厨师(sink),厨师做好大盘鸡(这是逻辑处理)之后告诉老板做好(state)老板把菜端上来(UI跟数据改变)
flutter_bloc 提供几个api 根据这几个API 就可以快速搭建bloc
BlocBuilder
BlocProvider
BlocProviderTree
BlocListener
BlocListenerTree
BlocBuilder
有三个属性 bloc condition builder
BlocBuilder(
bloc: ,这个添加bloc dart
condition: (previousState, currentState){ return true;},//可选默认返回true
builder: (BuildContext context, List state) {}state 返回数据
)。
BlocProvider
这个可以管理全局变量
BlocProvider(
bloc:,这个添加bloc dart 把这个bloc 传递其它字界面使用
child:LogIn(),子类
)
子widget 通过BlocProvider.of<LogBloc>(context) 获取这个bloc
如果涉及到push 可以通过这种模式传递
Navigator.push(context, new MaterialPageRoute(
builder: (Context)=>BlocProvider(
bloc:LogBloc(),
child:HomePage1(),
)));
BlocProviderTree
可以管理多个状态
一个widget 涉及多个state 可以用它管理
BlocProviderTree(
blocProviders: [
BlocProvider<BlocA>(bloc: BlocA()),
BlocProvider<BlocB>(bloc: BlocB()),
BlocProvider<BlocC>(bloc: BlocC()),
],
child: ChildA(),
)
介绍一下实践
做一个请求数据,拿到数据并展示UI
创建几个widget。ceshiBlocName CeshiEvent ,CeshiModel , CeShiState
CeshiEvent
负责触发逻辑处理
import 'ceshimodel.dart';
abstract class CeShiState{}
class CeshiSateNullInstallextends CeShiState{}
class CeshiStateDataextends CeShiState{
final Listarry;
CeshiStateData({this.arry});
CeshiStateDatacopyWith({
List arry,
}) {
return CeshiStateData(
arry: arry ??this.arry,
);
}
}
CeshiModel
数据模型
class CeshiModel{
final Stringtitle;
final Stringsource;
final intreplyCount;
final Stringtas;
final Stringboardid;
final Stringimgsrc;
final Listimgnewextra;
CeshiModel({this.title,this.source,this.replyCount,this.tas,this.boardid, this.imgsrc, this.imgnewextra});
}
ceshiBlocName
bloc 处理
Bloc<event,state> state可以对象,也可以是数组或者其它
CeshiEvent 是event
List<CeshiModel> 返回数据
class ceshiBlocNameextends Bloc<CeshiEvent,List<CeshiModel>>{
int_index=0;
Listarry=new List();
@override
// TODO: implement initialState
Listget initialState =>new List();//初始化结果
@override
Stream<List<CeshiModel>>mapEventToState(CeshiEvent event)async*{//数据处理 必须在这里面处理逻辑
event 触发事件
// TODO: implement mapEventToState
if(eventis CeshiLodale){//判断事件并返回处理结果
final posts =await _fetchPosts(_index, 20);
yield posts;//yield 返回数据
}
}
void ceshiDispachNull(){
dispatch(CeshiIntall());
}
void ceshiDispach(){
dispatch(CeshiLodale());
}
void ceshiDispach1(){
print('1111111111');
dispatch(CeshiLodale1());
}
Future>_fetchPosts(int startIndex, int limit)async {//请求数据
var tip=await NetUtil().request('${Url.listStr}offset=${startIndex}&size=${limit}&fn=2&spestr=reader_expert_1');
List tipArry=tip['tid'];
return tipArry.map((rawPost) {
return CeshiModel(
title:rawPost['title'],
replyCount:rawPost['replyCount'],
tas:'124' ,
source: rawPost['source'],
boardid: rawPost['boardid'],
imgsrc: rawPost['imgsrc'],
imgnewextra: rawPost['imgnewextra'],
);
}).toList();
}
}
主Main里面
final ceshiBlocName_ceshiBloc=ceshiBlocName();
Widgetbuild(BuildContext context) {
return Scaffold(
appBar:AppBar(
title:Text('1123'),
),
body:BlocBuilder(
bloc:_ceshiBloc,//根据具体bloc 处理数据
condition: (previousState, currentState){
return true;
},
builder: (BuildContext context, List state) {
//state 返回的数据
return widget;
}
);