• Bloc入门之Bloc详解


    背景

    之前一起学习了 Cubit ,现在进一步学习 Bloc

    区别

    首先应该了解一下 CubitBloc 各自的优势,以便按需使用

    在这里插入图片描述

    在这里插入图片描述
    从上面两图可以看出,在使用cubit时,UI通过function通知cubit进行数据处理和state更新,而使用bloc时,则是通过event来通知bloc进行数据处理和state更新。

    1. Cubit 的优势:

    简单

    创建一个 Cubit 时,只需要定义状态以及我们想要公开的改变状态的函数
    创建一个 Bloc 时,必须定义状态、事件和 EventHandler

    1. Bloc 的优势

    可溯源

    可以查看什么事件引发了状态改变。

    能够控制和转换事件的传入流

    像下面的样子,就很轻松实现防抖的效果:

    EventTransformer<T> debounce<T>(Duration duration) {
      return (events, mapper) => events.debounceTime(duration).flatMap(mapper);
    }
    
    CounterBloc() : super(0) {
      on<Increment>(
        (event, emit) => emit(state + 1),
        transformer: debounce(const Duration(milliseconds: 300)),
      );
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    上手

    1. 创建一个Bloc
    abstract class CounterEvent {}
    // 定义事件
    class CounterIncrementPressed extends CounterEvent {}
    
    class CounterBloc extends Bloc<CounterEvent, int> {
      CounterBloc() : super(0){// 可以指定初始状态,此处0
    	on<CounterIncrementPressed>((event, emit) { //EventHandler 事件处理函数
          // 可以通过 state getter 方法访问 bloc 的当前状态和通过 emit(state + 1) 改变状态.
          emit(state + 1);
        });
        // 可以重写onchange 来观察状态的改变
        @override
      	void onChange(Change<int> change) {
          super.onChange(change);
          print(change);
          //输出Change { currentState: 0, nextState: 1 }
      	}
    	//通过重写onTransition 我们还可以观察到时什么事件出发了本次状态改变
        @override
        void onTransition(Transition<CounterEvent, int> transition) {
          super.onTransition(transition);
          print(transition);
          // 输出Transition { currentState: 0, event: Instance of 'CounterIncrementPressed', nextState: 1 }
        }
        @override // bloc独有的,可以观察事件
        void onEvent(CounterEvent event) {
          super.onEvent(event);
          print(event);
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    这里有两点需要注意:

    Bloc 不可以直接发出状态,所有状态都应该是通过EventHandler函数发出的。

    Bloc 和 Cubits 都会忽略重复的状态,也就是说如果currentState与nextState一致,则本次状态变化会被忽略。

    除了在Bloc类里面重写方法来观察状态,也可以和之前一样也可以通过将观察部分单独写在BlocObserver类中:
    触发时,先触发Bloc本地的方法,然后再触发BlocObserver的全局方法。

    class SimpleBlocObserver extends BlocObserver {
      @override
      void onChange(BlocBase bloc, Change change) {
        super.onChange(bloc, change);
        print('${bloc.runtimeType} $change');
      }
    
      @override
      void onTransition(Bloc bloc, Transition transition) {
        super.onTransition(bloc, transition);
        print('${bloc.runtimeType} $transition');
      }
    
      @override
      void onError(BlocBase bloc, Object error, StackTrace stackTrace) {
        print('${bloc.runtimeType} $error $stackTrace');
        super.onError(bloc, error, stackTrace);
      }
      @override
      void onEvent(Bloc bloc, Object? event) {
        super.onEvent(bloc, event);
        print('${bloc.runtimeType} $event');
      }
      @override
      void onError(Object error, StackTrace stackTrace) {
        print('$error, $stackTrace');
        super.onError(error, stackTrace);
      }
    }
    
    
    Future<void> main() async {
        BlocOverrides.runZoned(
        () {
    	    CounterBloc()
    	        ..add(CounterIncrementPressed())
    	        ..close();  
        },
        blocObserver: SimpleBlocObserver(),
      );
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
  • 相关阅读:
    云服务器重启后无法获取IP地址怎么办?
    Ubuntu添加非root用户到Docker用户组
    【图像识别-指纹识别】指纹特征提取附matlab代码
    【Linux kernel基础】arch_initcall到底是怎么是一回事
    Ubunu安装一个更新版本的gda(2.3.2到 3.0.4)
    光模块字母含义及参数简称大全
    C++ 字符串操作
    Smart Tomcat的使用
    某旗小说107逆向(补发)
    k8s集群开启临时容器配置
  • 原文地址:https://blog.csdn.net/qq_18454025/article/details/126380726