Flutter BLoC 教程:使用 BLoC 模式进行状态管理

言鼎科技 2023-05-08 303

什么是区块链?

BLoC代表业务逻辑组件;它旨在将应用程序的业务逻辑与用户界面分开,使应用程序代码更加明确、可扩展和可测试。

  • 开发者:费利克斯·安格洛夫

  • 赞助商:Very Good Ventures、Stream、Miquido

  • 版本:flutter_bloc: ^8.0.1(写文章时)

Flutter BLoC 教程:使用 BLoC 模式进行状态管理

BLoC 设计模式的优缺点

在继续学习flutter bloc 教程之前,让我们检查一下 bloc 设计模式的一些优缺点。

使用 BLoC 的优点

  • 关于不同场景的优秀文档。

  • 将业务逻辑与 UI 分离,从而使代码易于理解。

  • 使产品更具可测试性。

  • 易于跟踪应用程序经历的状态。

使用 BLoC 的缺点

  • 学习曲线有点陡峭。

  • 不推荐用于简单应用

  • 更多样板代码,但可以通过扩展来处理。

Flutter BLoC 教程目标

我们将构建一个相对简单的应用程序来演示 BLoC 如何使用流来管理状态并为 bloc 编写一些测试。

我们将构建一个文本更改应用程序;按文本将更改并显示每个按钮。您可以参考下面的 GIF。

Flutter BLoC 教程:使用 BLoC 模式进行状态管理

初始设置

1.确保安装集团在你的编辑器中扩展;它将帮助创建项目所需的所有样板代码和文件(右键单击 lib 文件夹,它将为您提供为项目生成 bloc 的选项)。

2. 确保将你的 pubspec.yaml 文件与我的相匹配,以避免出现任何问题。

Flutter BLoC 教程:使用 BLoC 模式进行状态管理

想要轻松无忧地开发 Flutter 应用程序吗?
Bacancy 在这里等你!联系我们聘请 Flutter 开发人员,以出色的问题解决能力高效地满足您的项目要求。

了解 BLoC 概念:事件和状态

让游戏开始吧。

要了解 bloc 的工作原理,我们需要知道什么是事件和状态。

  • 事件:事件是应用程序的输入(例如 button_press 以加载图像、文本输入或我们的应用程序可能希望接收的任何其他用户输入)。

  • 状态:状态只是应用程序的状态,可以根据接收到的事件进行更改。

Bloc 管理这些事件和状态,即它接收事件流并将它们转换为状态流作为输出。

Flutter BLoC 教程:使用 BLoC 模式进行状态管理

创建事件

Flutter BLoC 教程:使用 BLoC 模式进行状态管理
@immutable抽象类 AppBlocEvent {
常量 AppBlocEvent();}
@immutable类 ChangeTextEvent 扩展 AppBlocEvent {
常量 ChangeTextEvent();}

在flutter bloc 教程中继续前进。在这里,我们创建了一个ChangeTextEvent,它会在单击按钮时触发。

我们有一个抽象的AppBlocEvent类,因为 Bloc 期望将单个事件添加到流中。尽管如此,由于一个应用程序中可以有多个事件,我们创建了一个抽象类并在我们想要创建任何新事件来处理多个事件并将其传递给 bloc 时扩展它。

创建状态

Flutter BLoC 教程:使用 BLoC 模式进行状态管理
@immutableAppState 类扩展 Equatable {
最终整数索引;
最终字符串文本;

常量 AppState.empty()
    : 指数 = 0,
      text = '初始文本';

常量 AppState({
  需要this.index,
  需要this.text,
});

@覆盖
List<Object> get props => [index, text];}

同样,我们可以在此应用程序中创建不同的状态。我们没有很多州。因此,我们创建了一个单一的状态来管理应用程序;然而,我们可以通过创建一个抽象的 appstate 并将其扩展到我们的自定义状态来创建类似于事件的多个状态。

  • AppState.empty只是应用程序最初加载的初始状态。

  • Equatable (get props)这里是用来和状态进行比较的。如果它们相等,它将用于测试区块。

使用 BLoC 模式的事件和状态管理

Flutter BLoC 教程:使用 BLoC 模式进行状态管理
AppBlocBloc 类扩展了 Bloc{
最终名单文本列表 = [
  '初始文本',
  '更改文本',
  '再次改变',
];
AppBlocBloc() : super(const AppState.empty()) {
  在((事件,发出){
    尝试 {
      int newIndex = state.index + 1;
      如果(新索引 >= textList.length){
        新指数 = 0;
      }
      发射(
        应用程序状态(
          指数:新指数,
          文本:textList[newIndex],
        ),
      );
    } on Exception catch (e) {
      // 忽略:avoid_print
      打印(e);
    }
  });
}}

说明
这是包含我们应用程序业务逻辑的部分。

  • 当通过单击按钮将 ChangeTextEvent 添加到流时执行,它接收事件,即您想要与触发事件一起传递的任何信息,您可以使用它访问它(如 event.any_info - 你必须更改你的事件相应地分类),emit 用于为该特定事件发出状态。
  • state.index 允许您访问应用程序的当前状态。

  • emit(AppState(…)): emit(…) 用于输出新状态并导致 build() 函数的重建。

把碎片放在一起。
到目前为止,事件、状态、集团和我们的应用程序的 UI 没有以任何方式连接。让我们开始将它们拼凑起来。

提供我们的 BLoC

Flutter BLoC 教程:使用 BLoC 模式进行状态管理
导入“包:flutter/material.dart”;导入“包:flutter_bloc/flutter_bloc.dart”;导入“包:text_change/text_controller.dart”;导入“bloc/app_bloc_bloc.dart”;导入“bloc/app_bloc_state.dart”;类 App 扩展 StatelessWidget {
 const App({Key?key}) : super(key: key);
 @覆盖
 小部件构建(BuildContext 上下文){
   返回 MaterialApp(
     标题:'颤振演示',
     主题:主题数据(
       primarySwatch: Colors.blue,
     ),
     家:BlocProvider(
       创建:(上下文)=> AppBlocBloc(),
       孩子:脚手架(
         应用栏:应用栏(
           title: const Text('文本变化'),
         ),
         正文:BlocConsumer(
           侦听器:(上下文,状态){},
           建设者:(上下文,状态){
             返回文本控制器(
               文本:state.text,
             );
           },
         ),
       ),
     ),
   );
 }}

说明:App.dart
BlocProvider(...):我们使用它来提供我们的 bloc 实例,方法是将它放置在应用程序的根目录下方,以便在整个应用程序中都可以访问它。

  • 创建:它创建我们的 AppBloBloc 的实例。

BlocConsumer(...):这是一切发生的地方。

  • 它有一个名为 listener 的属性,它监听状态变化,并且可以随着状态变化以特定方式对特定状态做出反应。

  • builder:它负责构建 UI 并在每次状态更改时重新构建。blocConsumer 还包含 listenWhen 和 buildWhen,正如名称所述,可以对其进行定制以对指定状态做出反应。

触发事件和状态

Flutter BLoC 教程:使用 BLoC 模式进行状态管理
类 TextChangeController 扩展 StatelessWidget {最终字符串文本;const TextChangeController({Key? key, required this.text}) : super(key: key);@覆盖小部件构建(BuildContext 上下文){
     返回列
        孩子们:[
           文本变化(
              文字:文字,
           ), // 文本变化
          高架按钮(
              onPressed: () =>
                   上下文.read().add(const ChangeTextEvent()),
             child: const Text('更改文本'),
        ), // 高架按钮
     ), //[ ]
  ); // 柱子
 ))

在这里,我们将ChangetTextEvent添加到事件流中,从而触发状态更改,从而导致 BlocConsumer 中的 builder() 重建,并将更改的文本显示在屏幕上。

你有它!!使用分离的 UI 和业务逻辑,您可以更改 UI 代码,只需插入 Bloc。它的工作原理是一样的。

您愿意构建一个演示应用程序并学习在您的 Flutter 应用程序中使用 freezed 吗?

Flutter 冻结示例

测试 BLoC 设计模式

为了测试 bloc,您需要两个包:

  • bloc_test

  • 颤动测试

只需在测试文件夹中,创建 app_bloc_test.dart 文件并开始编写测试。
在内部我们将测试两个条件:

  • 应用程序的初始状态,即 AppState.empty()。

  • 按下按钮时状态会发生变化。

给你!😊😊

Flutter BLoC 教程:使用 BLoC 模式进行状态管理
无效主要(){
块测试(
  '初始状态',
  构建:()=> AppBlocBloc(),
  验证:(appState)=>
      expect(appState.state, const AppState.empty(), reason: 'Initial State'),
);
块测试(
  '添加 MyEvent 时发出 [MyState]。',
  构建:()=> AppBlocBloc(),
  行为:(bloc) => bloc.add(const ChangeTextEvent()),
  期望:()=>常量[
    应用程序状态(
      指数:1,
      文本:'更改文本',
    ),
  ],
);}

解释

  • blocTest 来自 bloc_test 包。

  • build():它返回 AppBlocBloc() 的一个实例。

  • verify 和 expect 顾名思义它们匹配状态 expect(actual, matcher, reason)。

  • act:将事件添加到事件流中。

Github 存储库:Flutter BLoC 简单示例

随意克隆存储库:flutter-bloc-demo并开始试验代码。

结论

Flutter BLoC 教程有助于您开始使用 BLoC 模式进行状态管理。我们将带着另一个 Flutter 教程回来;到那时,请访问Flutter 教程页面并了解有关 Flutter 概念的更多信息。让我们知道您是否希望涵盖任何特定主题。给我们回信您的建议和反馈。快乐编码!


The End