【Flutter】Flutter状态管理框架:Bloc的计数器应用示例
# 【Flutter】Flutter 状态管理框架:Bloc 的计数器应用示例
# Flutter 计数器教程
在下面的教程中,我们会使用 Flutter 和 Bloc 库来开发一个计数器应用。
# 核心要点
- BlocObserver:用于观察 Bloc 内状态变化的 Widget。
- BlocProvider:为它的 children 提供 Bloc 的 Widget。
- BlocBuilder:根据新的 state 来绘制对应 Widget 的 Widget。
- 用 Cubit 替代 Bloc。两者有何不同?
- 通过 context.read 来触发 Event⚡。
# 新建项目和配置文件 yaml
我们先新建一个全新的 flutter 应用
1 | flutter create flutter_counter |
将下面代码复制粘贴到 pubspec.yaml
文件中
1 | name: flutter_counter |
安装依赖包 package
1 | flutter packages get |
# 项目架构
1 | ├── lib |
这个应用中我们使用的是功能驱动(feature-driven)的项目结构。这种项目结构可以让我们通过一个个独立的功能来扩展项目。在当前项目中,我们只需要做一个功能(也就是计数器),但是在将来我们可以通过加入更多功能来实现一个复杂的应用。
# BlocObserver
首先,我们需要了解如何创建一个 BlocObserver
, 它将帮助我们观察应用中所有的状态变化.
创建文件 lib/counter_observer.dart
:
1 | import 'package:bloc/bloc.dart'; |
在这个文件中,我们只重写了 onChange
,用来查看所有产生的状态(state)变化
注意: onChange
在 Bloc
和 Cubit
中发挥的作用是相同的。
# main.dart
接下来,用下面的代码替换 main.dart
里面的内容:
1 | import 'package:bloc/bloc.dart'; |
在上面的代码中,我们初始化了之前创建的 CounterObserver
并且通过 runApp
调用我们即将创建的 CounterApp
。
# Counter App
创建 lib/app.dart
:
CounterApp
是一个 home
是 CounterPage
的 MaterialApp
。
1 | import 'package:flutter/material.dart'; |
注意: CounterApp
扩展(extends) 自 MaterialApp
,所以在这里它是一个 MaterialApp
。 在大多数的情况下,我们会创建一个 StatelessWidget
或者 StatefulWidget
实例,并且通过 build
来绘制 Widget。但是现在我们并不需要绘制任何 Widget,所以我们直接从 MaterialApp
进行扩展(extends),这样更简单。
接下来,让我们来看下 CounterPage
!
# Counter Page
创建 lib/counter/view/counter_page.dart
:
CounterPage
是用来创建一个 CounterCubit
实例 (也就是接下来我们要创建的类的实例) 并把它提供给 CounterView
使用。
1 | import 'package:flutter/material.dart'; |
注意:分离(或者解耦) Cubit
创建部分的代码和 Cubit
使用部分的代码是非常重要的。这样使得代码更容易被测试或者被重复使用。
# Counter Cubit
创建 lib/counter/cubit/counter_cubit.dart
:
CounterCubit
类将提供两种方法:
increment
: 给当前状态(state)加 1decrement
: 给当前状态(state)减 1
设置 CounterCubit
状态的数据类型为 int
, 初始值是 0
。
1 | import 'package:bloc/bloc.dart'; |
小贴士:可以使用 VSCode Extension 或者 IntelliJ Plugin 自动创建新的 Cubit。
接下来我们来写 CounterView
,它将使用 state 并且和 CounterCubit
交互。
# Counter View
创建 lib/counter/view/counter_view.dart
:
CounterView
是用来绘制计数器上的数字以及两个用于增加和减少数字的 FloatingActionButtons。
1 | import 'package:flutter/material.dart'; |
用 BlocBuilder
把 Text
包起来,这样每一次 CounterCubit
状态变化的时候里面的文字就会更新。 另外,使用 context.read<CounterCubit>()
来接入 CounterCubit
实例。
注意:只有 Text
需要被 BlocBuilder
包起来,因为这是唯一一个会随着 CounterCubit
状态(state) 变化而变化的组件。请不要包裹任何不随状态(state) 改变而改变的 Widget, 从而避免绘制不必要的组件。
# Barrel
创建 lib/counter/counter.dart
:
加入 counter.dart
用来导出所有有关计数器的公共接口。
1 | export 'cubit/counter_cubit.dart'; |
大功告成!我们已经将表现层(presentation layer)从数据逻辑层(business logic layer)中分离出来。 CounterView
不会知道用户点击按钮的时候发生了什么,它只是通知了 CounterCubit
。 而且, CounterCubit
不会知道状态(也就是计数器的值)是什么, 它只是根据被调用的方法来发出新的状态。
最后,通过执行 flutter run
让我们在真实设备或者模拟器上运行它。
# 关于我
Brath 是一个热爱技术的 Java 程序猿,公众号「InterviewCoder」定期分享有趣有料的精品原创文章!
非常感谢各位人才能看到这里,原创不易,文章如果有帮助可以关注、点赞、分享或评论,这都是对我的莫大支持!