写点什么

Flutter_bloc 框架使用笔记,后续估计都不太会用了

用户头像
Android架构
关注
发布于: 21 小时前

final String phone;


@override_Regi


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


sterPageState createState() => _RegisterPageState();}


class _RegisterPageState extends State<RegisterPage> {final _registerBloc = RegisterBloc(RegisterState());


@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(LS.of(context, "register")),),body: BlocProvider<RegisterBloc>(create: (_) => _registerBloc,child: RegisterScreen(widget.phone),),);}}


作为一个主体的页面,定义了 route 名称。 可以使用StatelessWidget。因为正常也没什么状态管理


在 state 里面的 builder 里构建了BlocProvider


body: BlocProvider<RegisterBloc>(create: (_) => _registerBloc,child: RegisterScreen(widget.phone),)


这里是为后续的节点注册了一个RegisterBloc, 从这个节点下级的 widget 就可以通过Provider.of<RegisterBloc>来获取。 当然也可以有其他的方式比如context.read<RegisterBloc>来获取。


这里也可以把 bloc 传给 screen,可以方便在 screen 里面获取 bloc。而不是通过在配置树里查找 bloc。能稍微减少些性能消耗。


  1. screen


screen 主要是构建配置页面内容用。


class RegisterScreen extends StatelessWidget {const RegisterScreen(this.phone, {Key? key,}) : super(key: key);


final String phone;


@overrideWidget build(BuildContext context) {return BlocListener<RegisterBloc, RegisterState>(listener: (ctx, state) {if (state.status.isSubmissionInProgress) {EasyLoading.show(maskType: EasyLoadingMaskType.clear, dismissOnTap: false);return;}if (state.status.isSubmissionFailure) {EasyLoading.dismiss();var message = LS.of(context, "register_error");EasyLoading.showError('{state.errMessage ?? ''}');return;}if (state.status.isSubmissionSuccess) {EasyLoading.dismiss();showCupertinoDialog(context: context,builder: (context) {returnAlertDialog(content: Text(LS.of(context, "register_success")),actions: [TextButton(onPressed: (){Navigator.of(context).popUntil(ModalRoute.withName("/"));}, child: Text(LS.of(context, "confirm")))],);});}},child: Align(alignment: Alignment(0, -1),child: Padding(padding: const EdgeInsets.only(top: 31, left: 36, right:36),child: Column(children: [_UsernameInput(),_PasswordInput(),_ConfirmPasswordInput(),const SizedBox(height: 20,),_RegisterButton()]),),));}}


class _RegisterButton extends StatelessWidget {@overrideWidget build(BuildContext context) {return BlocBuilder<RegisterBloc, RegisterState>(builder: (context, state) {return CircleRectButton(child: Text(LS.of(context, "register"), style: TextStyle(letterSpacing: 20)),onPressed: state.status.isValidated? () async {context.read<RegisterBloc>().add(RegisterSubmitEvent());}: null);});}}


BlocListener: 通过BlocListener来监听状态消息,收到消息 child 不会 rebuild。适合拿来弹出加载页,错误信息等。


BlocBuilder 通过BlocBuilder来包装需要修改的内容。 这里的在组装页面的时候尽量在涉及到更新的地方使用 BlocBuilder,也尽可能的考虑buildwhen 属性。保持当必须要更新时才重新 build 的思路。


  1. bloc


bloc 在封装后没什么逻辑,他的思路就是接受页面的事件,转为状态变更返回给页面。


class RegisterBloc extends Bloc<RegisterEvent, RegisterState> {


RegisterBloc(RegisterState initialState) : super(initialState);


@overrideStream<RegisterState> mapEventToState(RegisterEvent event,) async* {try {yield* event.applyAsync(currentState: state, bloc: this);} catch (, stackTrace) {developer.log('$', name: 'RegisterBloc', error: _, stackTrace: stackTrace);yield state;}}}


将对应的事件处理放在 event 里面去执行显然更符合设计模式。代码也会更清晰,而不用做很多判断


if(event is event){do()} else if (event is event) {do()}


  1. event


@immutableabstract class RegisterEvent {const RegisterEvent();Stream<RegisterState> applyAsync({required RegisterState currentState, required RegisterBloc bloc});}


class UsernameChangeEvent extends RegisterEvent {const UsernameChangeEvent(this.username);final String username;


Stream<RegisterState> applyAsync({required RegisterState currentState, required RegisterBloc bloc}) async* {var input = UsernameInput.dirty(username);var status = Formz.validate([input, currentState.password, currentState.confirmPassword]);yield currentState.copyWith(username: input, status: status);}


}


抽象 event,定义事件接口。 子类 event 来接收参数,实现事件接口并抛出新的状态给页面。


  1. state

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Flutter_bloc框架使用笔记,后续估计都不太会用了