软件编程
位置:首页>> 软件编程>> flutter编程>> flutter Bloc 实现原理示例解析

flutter Bloc 实现原理示例解析

作者:李小轰_Rex  发布时间:2023-07-18 08:00:39 

标签:flutter,Bloc,实现原理

序言

flutter开发中,我们使用 bloc 框架,基于状态变更进行响应式开发。本篇文章,小轰将 bloc 核心业务块进行拆解简化,聊一聊它的实现思想,bloc 核心能力分为如下两点:

  • 添加事件 event,将 '事件流' 转换为 '状态流' state

  • 监听 bloc 流,每次 state 状态变更,通知 widget 更新

下面,用自定义Bloc的方式,来给大家讲解一下Bloc的原理构造

1. 事件流 > 状态流 (中转)

首先,我们将bloc代码简化,我们来看看bloc如何将事件流转换为状态流。简化代码如下:

import 'dart:async';
abstract class ACubit<State> {
 StreamController<State> _controller = StreamController<State>.broadcast();
 State _state;
 State get state => _state;
 ACubit(this._state);
 ///发送State状态到流里面
 void emit(State state) {
   if (_controller.isClosed) return;
   if (state == _state) return;
   _state = state;
   _controller.add(_state);
 }
 ///提供方法外部监听State
 StreamSubscription<State> listen(
   void Function(State state) onData, {
   Function onError,
   void Function() onDone,
   bool cancelOnError,
 }) {
   return _controller.stream.listen(
     onData,
     onError: onError,
     onDone: onDone,
     cancelOnError: cancelOnError,
   );
 }
 Future<void> close() {
   return _controller.close();
 }
}

ACubit提供最基础的能力。提供listen方法给外部监听 'State' 变更;emit方法用来响应state状态变更。

abstract class ABloc<Event, State> extends ACubit<State> {
 final _eventController = StreamController<Event>.broadcast();
 ABloc(State initState) : super(initState) {
   _bindEventToState();
 }
 ///发送事件
 void add(Event event) {
   if (_eventController.isClosed) return;
   _eventController.add(event);
 }
 ///需上层实现 (根据event转成state)
 Stream<State> mapEventToState(Event event);
 ///将事件流(event)转换成状态流(state)
 _bindEventToState() {
   _eventController.stream
       // asyncExpand 将流内容进行类型转换,结果还是流
       .asyncExpand((event) => mapEventToState(event))
       .listen((nextState) {
     ///将nextState与当前state进行比对,比对成功后放入流中
     emit(nextState);
   });
 }
}

ABloc 是我们直接使用的基类。在构造函数中调用了_bindEventToState将事件流转换为状态流。

2. 使用 BlocBuilder 实时监听状态变更, 如何实现的呢?

小轰做了一个简化版的原理讲解:

import 'package:flutter/material.dart';
import 'a_bloc.dart';
class BlocBuilder<T extends ACubit<S>, S> extends StatefulWidget {
 final T cubit;
 final Widget Function(BuildContext context, S state) builder;
 const BlocBuilder({
   Key key,
   @required this.cubit,
   @required this.builder,
 }) : super(key: key);
 @override
 _BlocBuilderState<S> createState() => _BlocBuilderState<S>();
}
class _BlocBuilderState<S> extends State<BlocBuilder> {
 void _update() {
   setState(() {});
 }
 @override
 void initState() {
   ///监听state状态变更
   widget.cubit?.listen((_) {
     _update();
   });
   super.initState();
 }
 @override
 void dispose() {
   widget.cubit?.close();
   super.dispose();
 }
 @override
 Widget build(BuildContext context){
   return widget.builder(
     context,
     widget.cubit.state,
   );
 }
}

封装 BlocBuilder

  • 构造函数中传入自定义的 bloc (继承ABloc),builder 传参用于获取每次 state 变更通知。

  • initState初始化方法中对cubit进行状态监听,每次状态变更直接调用setState方法进行页面更新

调用示例如下:

return BlocBuilder<CountBloc, CountState>(
     cubit: CountBloc(CountState(1)),
     builder: (context, state) {
      return Container(...省略业务代码)
     },
   )

来源:https://juejin.cn/post/7007683747512320014

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com