flutter Bloc 实现原理示例解析

 更新时间:2022年11月15日 08:44:47   作者:李小轰_Rex  
这篇文章主要为大家介绍了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(...省略业务代码)
      },
    )

总结

bloc 库中引用了provider 等三方库。基于InheritedWidget实现了数据共享能力。本篇文章,小轰只为演示Bloc核心的处理思想。详细请查阅Bloc源码。

扩展

InheritedProvider 实现数据共享 Bloc同时add两次只响应一次问题处理

以上就是flutter Bloc 实现原理示例解析的详细内容,更多关于flutter Bloc 实现原理的资料请关注脚本之家其它相关文章!

相关文章

  • Android实现手机监控摄像头

    Android实现手机监控摄像头

    这篇文章主要为大家详细介绍了Android实现手机监控摄像头,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • Android控件系列之ImageView使用方法

    Android控件系列之ImageView使用方法

    Android控件系列之ImageView使用方法,学习android的朋友可以参考下
    2012-11-11
  • android使用PopupWindow实现页面点击顶部弹出下拉菜单

    android使用PopupWindow实现页面点击顶部弹出下拉菜单

    这篇文章主要给大家介绍android使用PopupWindow实现页面点击顶部弹出下拉菜单,实现此功能主要通过PopupWindow方法,代码也很简单,需要的朋友可以参考下
    2015-08-08
  • Android 中利用 ksoap2 调用 WebService的示例代码

    Android 中利用 ksoap2 调用 WebService的示例代码

    这篇文章主要介绍了Android 中利用 ksoap2 调用 WebService的示例代码,非常具有实用价值,需要的朋友可以参考下
    2017-09-09
  • Android入门:多线程断点下载详细介绍

    Android入门:多线程断点下载详细介绍

    本篇文章主要介绍了 Android多线程断点下载,即文件在下载一部分中断后,可继续接着已有进度下载,有需要的可以了解一下。
    2016-11-11
  • Android-App增量更新的使用姿势

    Android-App增量更新的使用姿势

    增量更新根据字面理解就是下载增加的那部分来达到更新的目获取旧的Apk安装包的签名和已合并成新的Apk安装包的签名,对比签名是否一致当你下载差异文件时,可以让服务器给你返回新的Apk合并成功后文件的md5,当你合并成功后,通过校验文件的md5值,达到校验文件完整性。
    2016-04-04
  • Android 更新RecyclerView的好方法

    Android 更新RecyclerView的好方法

    在使用RecyclerView的时候不免要修改RecyclerView的数据,使用notifyDataSetChanged()来刷新界面,但是当数据多,而只是修改了一点的数据,或者刷新比较频繁,这样就会导致界面卡顿,用户交互特别不好,这时可以使用RecyclerView方法解决,具体实现代码大家参考下本文吧
    2017-06-06
  • 系统应用根据Uri授予权限方法详解

    系统应用根据Uri授予权限方法详解

    这篇文章主要为大家介绍了系统应用根据Uri授予权限方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • Android Service中方法使用详细介绍

    Android Service中方法使用详细介绍

    这篇文章主要介绍了android service中方法使用详细介绍的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-09-09
  • Android开启闪光灯的方法 Android打开手电筒功能

    Android开启闪光灯的方法 Android打开手电筒功能

    这篇文章主要为大家详细介绍了Android开启闪光灯的方法,Android打开手电筒功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-07-07

最新评论