Flutter_bloc

2020/2/9 posted in  Flutter

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: blockA,#这个添加bloc dart
    condition: (previousState, currentState){ 
            return true;
        },//可选默认返回true
    builder: (BuildContext context, List state) {} #state 返回数据
)。

BlocProvider

这个可以管理全局变量

BlocProvider(
    bloc: blockA,#这个添加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 CeshiStateData extends 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 state可以对象,也可以是数组或者其它
CeshiEvent 是event
List 返回数据

class ceshiBlocName extends 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;
        }))
    );