Flutter 88: 初识状态管理 Bloc (三)

简介: 0 基础学习 Flutter,第八十八步:简单了解 FlutterBloc 聚合方式状态管理 (三)!

      小菜刚学习了 FlutterBloc 的基本用法,使用的场景还很简单,主要是单一 Bloc 的应用,今天小菜继续尝试多个 Bloc 共用的场景;
      小菜继续完善前两节的 Demo,添加了随机变更背景色的功能(并没有实际意义,仅为了学习新知识点而已);

FlutterBloc

MultiBlocProvider

      对于多个 Bloc 的应用场景,小菜尝试了如下三种方式:

方案一:

      在 build() 外创建和初始化 Bloc;小菜认为这种方式一定程度上扩大了 Bloc 的作用域;

NumberBloc _numBloc = NumberBloc();
ColorBloc _colorBloc = ColorBloc();
  
@override
Widget build(BuildContext context) {
  return BlocBuilder<NumberBloc, int>(
      bloc: _numBloc,
      condition: (previousState, state) {
        print('BlocPage.condition->$previousState==$state');
        return state <= 30 ? true : false;
      },
      builder: (context, count) {
        return BlocBuilder<ColorBloc, Color>(
            bloc: _colorBloc,
            builder: (context, color) {
              return Scaffold(
                  appBar: AppBar(title: Text('Bloc Page'), actions: <Widget>[_settingWid()]),
                  body: Container(color: _colorBloc.state, child: _numberWid()),
                  floatingActionButton: _floatingWid());
            });
      });
}
方案二:

      通过多个 BlocProvider 嵌套方式对 Bloc 进行创建;小菜认为这种方式嵌套层级较多,略微有一些繁琐;

@override
Widget build(BuildContext context) {
  return BlocProvider(
      create: (BuildContext context) => _numBloc = NumberBloc(),
      child: BlocBuilder<NumberBloc, int>(
          bloc: _numBloc,
          condition: (previousState, state) {
            print('BlocPage.condition->$previousState==$state');
            return state <= 30 ? true : false;
          },
          builder: (context, count) {
            return BlocProvider(
                create: (BuildContext context) => _colorBloc = ColorBloc(),
                child: BlocBuilder<ColorBloc, Color>(
                    bloc: _colorBloc,
                    builder: (context, color) {
                      return Scaffold(
                          appBar: AppBar(title: Text('Bloc Page'), actions: <Widget>[_settingWid()]),
                          body: Container(color: _colorBloc.state, child: _numberWid()),
                          floatingActionButton: _floatingWid());
                    }));
          }));
}
方案三:

      便是采用 MultiBlocProvider 聚合绑定方式,作为一个 WidgetBlocProvider 方式聚合创建和初始化,小菜更倾向于这种方式,层级更清晰简洁;

@override
Widget build(BuildContext context) {
  return MultiBlocProvider(
      providers: [
        BlocProvider(create: (BuildContext context) => _numBloc = NumberBloc()),
        BlocProvider(create: (BuildContext context) => _colorBloc = ColorBloc())
      ],
      child: BlocBuilder<NumberBloc, int>(
          bloc: _numBloc,
          condition: (previousState, state) {
            print('BlocPage.condition->$previousState==$state');
            return state <= 30 ? true : false;
          },
          builder: (context, count) {
            return BlocBuilder<ColorBloc, Color>(
                bloc: _colorBloc,
                builder: (context, color) {
                  return Scaffold(
                      appBar: AppBar(title: Text('Bloc Page'), actions: <Widget>[_settingWid()]),
                      body: Container(color: _colorBloc.state, child: _numberWid()),
                      floatingActionButton: _floatingWid());
                });
          }));
}

MultiBlocListener

      对于多个 Bloc 的场景,对于其 Bloc 的监听也可以有多种方式;

方案一:

      对应于 BlocProvider 的方式,小菜合并前两种,尝试 listener 嵌套方式进行监听;

@override
Widget build(BuildContext context) {
  return BlocProvider(
      create: (BuildContext context) => _numBloc = NumberBloc(),
      child: BlocListener<NumberBloc, int>(
          bloc: _numBloc,
          listener: (context, state) => print('BlocListener--->NumberBloc--->$state'),
          child: BlocBuilder<NumberBloc, int>(
              bloc: _numBloc,
              condition: (previousState, state) {
                print('BlocPage.condition->$previousState==$state');
                return state <= 30 ? true : false;
              },
              builder: (context, count) {
                return BlocProvider(
                    create: (BuildContext context) => _colorBloc = ColorBloc(),
                    child: BlocListener<ColorBloc, Color>(
                        bloc: _colorBloc,
                        listener: (context, state) => print('BlocListener--->ColorBloc--->$state'),
                        child: BlocBuilder<ColorBloc, Color>(
                            bloc: _colorBloc,
                            builder: (context, color) {
                              return ScaffoldappBar: AppBar(title: Text('Bloc Page'), actions: <Widget>[_settingWid()]),
                                  body: Container(color: _colorBloc.state, child: _numberWid()),
                                  floatingActionButton: _floatingWid());
                            })));
              })));
}
方案二:

      MultiBlocListener 作为一个 Widget,将 listener 聚合在一起;效果完全相同,但消除了嵌套提高了 Code 可读性;

@override
Widget build(BuildContext context) {
  return MultiBlocProvider(
      providers: [
        BlocProvidercreate: (BuildContext context) => _numBloc = NumberBloc()),
        BlocProvider(create: (BuildContext context) => _colorBloc = ColorBloc())
      ],
      child: MultiBlocListener(
          listeners: [
            BlocListener<NumberBloc, int>(listener: (context, state) => print('BlocListener--->NumberBloc--->$state')),
            BlocListener<ColorBloc, Color>(listener: (context, state) => print('BlocListener--->ColorBloc--->$state'))
          ],
          child: BlocBuilder<NumberBloc, int>(
              bloc: _numBloc,
              condition: (previousState, state) {
                print('BlocPage.condition->$previousState==$state');
                return state <= 30 ? true : false;
              },
              builder: (context, count) {
                return BlocBuilder<ColorBloc, Color>(
                    bloc: _colorBloc,
                    builder: (context, color) {
                      return Scaffold(
                          appBar: AppBar(title: Text('Bloc Page'), actions: <Widget>[_settingWid()]),
                          body: Container(color: _colorBloc.state, child: _numberWid()),
                          floatingActionButton: _floatingWid());
                    });
              })));
}

小感想

      小菜尝试了 ProviderBloc 两种状态管理工具,均是对 Stream 的操作,小菜认为各有各的优势,不能互相替代;
      Bloc 方式最大的优势是把页面 UI 与业务逻辑拆分的更清晰,不管是 MVC 或 MVP 方式都更方便的融入应用;Provider 的应用更加简单,无需考虑拆分的情况;
      小菜在了解源码的时候发现一个有趣的现象,FlutterBloc 也是对 Provider 的一种封装;

      现在针对状态管理的方式还有很多其他方式,小菜认为无需强制使用某一种,选择适合自己对就好;


      FlutterBloc 案例源码


      小菜对 Bloc 的尝试暂时告一个段落,对于更高级的用法在实际应用中再进行尝试和学习;如有错误,请多多指导!

来源: 阿策小和尚

目录
相关文章
|
26天前
|
存储 JavaScript 前端开发
在Flutter开发中,状态管理至关重要。随着应用复杂度的提升,有效管理状态成为挑战
在Flutter开发中,状态管理至关重要。随着应用复杂度的提升,有效管理状态成为挑战。本文介绍了几种常用的状态管理框架,如Provider和Redux,分析了它们的基本原理、优缺点及适用场景,并提供了选择框架的建议和使用实例,旨在帮助开发者提高开发效率和应用性能。
34 4
|
1月前
|
存储 Shell 开发工具
Flutter&鸿蒙next 中使用 MobX 进行状态管理
本文介绍了如何在 Flutter 中使用 MobX 进行状态管理。MobX 是一个基于观察者模式的响应式编程库,通过 `@observable` 和 `@action` 注解管理状态,并使用 `Observer` 小部件自动更新 UI。文章详细讲解了 MobX 的核心概念、如何集成到 Flutter 项目中以及具体的代码示例。适合希望在 Flutter 应用中实现高效状态管理的开发者阅读。
100 9
|
1月前
|
存储 开发者
Flutter&鸿蒙next 使用 BLoC 模式进行状态管理详解
本文详细介绍了如何在 Flutter 中使用 BLoC 模式进行状态管理。BLoC 模式通过将业务逻辑与 UI 层分离,利用 Streams 和 Sinks 实现状态管理和 UI 更新,提高代码的可维护性和可测试性。文章涵盖了 BLoC 的基本概念、实现步骤及代码示例,包括定义 Event 和 State 类、创建 Bloc 类、提供 Bloc 实例以及通过 BlocBuilder 更新 UI。通过一个简单的计数器应用示例,展示了 BLoC 模式的具体应用和代码实现。
85 1
|
1月前
|
开发工具 开发者
Flutter&鸿蒙next 状态管理高级使用:深入探讨 Provider
本文深入探讨了 Flutter 中 Provider 的高级用法,涵盖多 Provider 组合、Selector 优化性能、ChangeNotifierProxyProvider 管理依赖关系以及自定义 Provider。通过这些技巧,开发者可以构建高效、可维护的响应式应用。
81 2
|
2月前
|
开发工具 开发者
Flutter&鸿蒙next 状态管理高级使用:深入探讨 Provider
Flutter&鸿蒙next 状态管理高级使用:深入探讨 Provider
|
1月前
|
缓存 JavaScript API
Flutter&鸿蒙next 状态管理框架对比分析
在 Flutter 开发中,状态管理至关重要,直接影响应用的性能和可维护性。本文对比分析了常见的状态管理框架,包括 setState()、InheritedWidget、Provider、Riverpod、Bloc 和 GetX,详细介绍了它们的优缺点及适用场景,并提供了 Provider 的示例代码。选择合适的状态管理框架需考虑应用复杂度、团队熟悉程度和性能要求。
109 0
|
2月前
【Flutter】状态管理:Provider状态管理
【Flutter】状态管理:Provider状态管理
24 0
|
2月前
|
UED
flutter:动画&状态管理 (十三)
本文档介绍了Flutter中`animatedList`的使用方法和状态管理的示例。`animatedList`用于创建带有动画效果的列表,示例代码展示了如何添加、删除列表项,并执行相应的动画效果。状态管理部分通过一个简单的点击切换颜色的示例,演示了如何在Flutter中管理组件的状态。
|
5月前
|
容器
flutter 布局管理【详解】
flutter 布局管理【详解】
45 3
|
4月前
Flutter 状态管理新境界:多Provider并行驱动UI
Flutter 状态管理新境界:多Provider并行驱动UI
81 0