博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Flutter-BLoC-第三讲
阅读量:6423 次
发布时间:2019-06-23

本文共 4852 字,大约阅读时间需要 16 分钟。

本篇已同步到 ,欢迎常来。

[TOC]

本文为 《Flutter Bloc Package》 的译文,,若转载本译文请注明出处。

在使用Flutter工作一段时间之后,我决定创建一个软件包以帮助我经常使用的东西:BLoC模式。 对于那些不熟悉BLoC模式的人来说,它是一种设计模式,有助于将表示层与业务逻辑分开。你在了解更多。

使用BLoC模式可能具有挑战性,因为需要建立对Streams和Reactive Programming的理解。但它的核心是BLoC非常简单:

BLoC 将event流作为输入,并将它们转换为state流作为输出。

我们现在可以在的帮助下使用这种强大的设计模式。

该软件包抽象了模式的反应方面,允许开发人员专注于将事件(event)转换为状态(state)。

让我们从定义这些术语开始......

词汇表

Events

Events 是Bloc的输入。它们通常是UI事件,例如按钮按下。Events被分发(dispatched)并且被转换为States。

States

States 是Bloc的输出。表示组件可以监听状态流 并根据给定状态重绘其自身的部分(BlocBuilder有关详细信息,请参阅参考资料)。

Transitions

Transitions 发生在 调用mapEventToState之后 但在更新了bloc的state之前 调度了一个Event

现在我们了解事件和状态,我们可以看一下Bloc API。

BLOC API

mapEventToState

当一个类继承Bloc时,必须实现 mapEventToState 方法, 该函数将传入事件作为参数。 只要UI层触发一个事件,就会调用 mapEventToState。 mapEventToState 必须将该event转换为新state,并以UI层使用的Stream形式返回新状态。

dispatch

dispatch 是一个 接受 event 并触发 mapEventToState 的方法。 可以从表示层调用dispatch 或 从Bloc内部(见例子)并通知Bloc一个新 event。

initialState

initialState是处理任何事件之前的状态(在mapEventToState被调用之前)。 如果未实现,则为initialState null。

transform

transform是一个 在调用mapEventToState之前 可以重写以转换 Stream . 这允许使用distinct() 和 debounce() 的操作。

onTransition

onTransition 是一个 每次 transform 发生时都可以重写以进行处理 的方法。 调度新event 并调用mapEventToState时发生transition。 onTransition 在更新 bloc 状态之前 被调用。 这是添加特定于块的日志记录/分析的好地方

让我们创建一个counter bloc!

enum CounterEvent { increment, decrement }class CounterBloc extends Bloc
{ @override int get initialState => 0; @override Stream
mapEventToState(CounterEvent event) async* { switch (event) { case CounterEvent.decrement: yield currentState - 1; break; case CounterEvent.increment: yield currentState + 1; break; } }}复制代码

创建一个BLoC 需要作如下操作:

  • 定义所有 event 和 state
  • 继承Bloc
  • 重写 initialState 和 mapEventToState

在这种情况下,我们的 events 是CounterEvents ,states 是 integers

CounterBloc 转换 CounterEvents 为 integers。

我们可以通过 dispatch 来 通知CounterBloc 事件

void main() {  final counterBloc = CounterBloc();  counterBloc.dispatch(CounterEvent.increment);  counterBloc.dispatch(CounterEvent.decrement);}复制代码

为了观察状state 的 转换(Transitions),我们可以重写onTransition。

enum CounterEvent { increment, decrement }class CounterBloc extends Bloc
{ @override int get initialState => 0; @override void onTransition(Transition
transition) { print(transition); } @override Stream
mapEventToState(CounterEvent event) async* { switch (event) { case CounterEvent.decrement: yield currentState - 1; break; case CounterEvent.increment: yield currentState + 1; break; } }}复制代码

现在,每当发出(dispatch)一个CounterEvent我们的Bloc将响应一个新的integer状态,我们将看到一个transition被输出到控制台。

现在让我们使用Flutter构建一个UI,并使用flutter_bloc 包将UI连接到我们的CounterBloc。

BlocBuilder

BlocBuilder是一个Flutter小部件,它需要一个Bloc和一个构建器函数。 BlocBuilder处理构建窗口小部件以响应新state。 BlocBuilder与StreamBuilder非常相似,但它有一个更简单的API来减少所需的样板代码量。

BlocProvider

BlocProvider是一个Flutter小部件,它通过 BlocProvider.of(context)为其子女提供了一个bloc。 它用作依赖注入(DI)小部件, 这样一个bloc实例 可以被提供给子树中的多个小部件。

现在让我们构建 counter App

class App extends StatefulWidget {  @override  State
createState() => _AppState();}class _AppState extends State
{ final CounterBloc _counterBloc = CounterBloc(); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', home: BlocProvider
( bloc: _counterBloc, child: CounterPage(), ), ); } @override void dispose() { _counterBloc.dispose(); super.dispose(); }}class CounterPage extends StatelessWidget { @override Widget build(BuildContext context) { final CounterBloc _counterBloc = BlocProvider.of
(context); return Scaffold( appBar: AppBar(title: Text('Counter')), body: BlocBuilder
( bloc: _counterBloc, builder: (BuildContext context, int count) { return Center( child: Text( '$count', style: TextStyle(fontSize: 24.0), ), ); }, ), floatingActionButton: Column( crossAxisAlignment: CrossAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end, children:
[ Padding( padding: EdgeInsets.symmetric(vertical: 5.0), child: FloatingActionButton( child: Icon(Icons.add), onPressed: () { _counterBloc.dispatch(CounterEvent.increment); }, ), ), Padding( padding: EdgeInsets.symmetric(vertical: 5.0), child: FloatingActionButton( child: Icon(Icons.remove), onPressed: () { _counterBloc.dispatch(CounterEvent.decrement); }, ), ), ], ), ); }}复制代码

该App小部件是StatefulWidget,负责创建和销毁 CounterBloc。 它让 CounterBloc 使用 BlocProvider 小部件可用于 CounterPage 小部件。

CounterPage小部件是StatelessWidget, 它使用BlocBuilder重建UI以响应CounterBloc的状态变化。

此时,我们已经成功地将我们的表示层与业务逻辑层分开。请注意,CounterPage窗口小部件对用户点击按钮时发生的情况一无所知。小部件只是告诉CounterBloc用户按下了递增或递减按钮。

有关更多示例和详细文档,请查看。

相关链接:

你可能感兴趣的文章
深入理解Lock
查看>>
vim的块选择
查看>>
HTML --块
查看>>
一个不错的loading效果
查看>>
Debian允许root用户登录
查看>>
linux的文件系统
查看>>
上云利器,K8S应用编排设计器之快到极致
查看>>
袋鼠云服务案例系列 | 从DB2到MySQL,某传统金融平台的互联网转型之路
查看>>
RealServer配置脚本
查看>>
九月份技术指标 华为交换机的简单配置
查看>>
python 写json格式字符串到文件
查看>>
分布式文件系统MogileFS
查看>>
Java23种设计模式案例:策略模式(strategy)
查看>>
XML解析之DOM4J
查看>>
图解微服务架构演进
查看>>
SQL PATINDEX 详解
查看>>
一些常用的网络命令
查看>>
CSP -- 运营商内容劫持(广告)的终结者
查看>>
DIV+CSS命名规范有助于SEO
查看>>
web项目buildPath与lib的区别
查看>>