Flutter BLoC 异步通信、BlocBuilder的基本使用、BlocProvider的初探
题记
—— 执剑天涯,从你的点滴积累开始,所及之处,必精益求精。
Flutter是谷歌推出的最新的移动开发框架。
在 Flutter 中可用于异步通信的方案有如下:
- Provider ( Provider 异步通信、Provider状态管理)
- ValueNotifier 点击查看详情
- Stream: StreamController的使用详情 | StreamBuilder组件的结合使用 | StreamBuilder 实现的倒计时进度圆圈
- EventBus (不考虑使用)
- Bloc BLoC 异步通信、BlocBuilder的基本使用、BlocProvider的初探
1 前言
BloC 全称是 Business Logic Component(业务逻辑组件),主要作用就是将业务逻辑和UI组件分离开。
在Flutter项目开发中,一般的项目中,会有网络请求的代码与Widget构建的UI界面写一起,随着业务的不断积累,代码量也越来越大,维护的复杂度也会随着增加。
BLoC模式可以将Widget构建UI的代码与业务处理的代码分离出来,在BLoC模式下的应用程序,一般会有全局的BLoC,每一个页面也会对应有一个独立的BLoC。
使用BloC模式,Flutter项目应用里的所有组件都在一个事件流,其中一部分组件可以订阅事件,另一部分组件则消费事件
2 BloC 的基本使用
BloC是一种架构模式也是一种编程思想,在Flutter中使用BloC时,首先要引入bloc库
dependencies:
flutter_bloc: ^6.0.6
然后将依赖库拉取到本地
flutter packages get
在Flutter BloC模式开发中常用组件有BlocBuilder、BlocProvider、BlocListener和BlocConsumer等等。
在这里使用Bloc模式开发一个时间计时器 运行效果如下图所示:
首先来看程序入口,在这里使用到了 BlocProvider ,BlocProvider相当于一个组合者,它将 Bloc 、事件、消费组合在一起,在本文章 第四小节有详细概述,代码如下:
///flutter应用程序中的入口函数
void main() => runApp(BlocMainApp());
///应用的根布局
class BlocMainApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
///构建Materia Desin 风格的应用程序
return BlocProvider<CounterBloc>(
create: (context) => CounterBloc(""),
child: MaterialApp(
///Android应用程序中任务栏中显示应用的名称
title: "配制",
theme: ThemeData(
accentColor: Colors.blue,
///默认是 Brightness.light
brightness: Brightness.light,
),
///默认的首页面
home: TestBlocTimePage(),
),
);
}
}
对于 TestBlocTimePage 就是 MaterialApp中设置默认显示的 home 首页面,是自定义的一个 Widget 页面,在这里使用 Scaffold 来构建页面主体,然后初始化了一个 计时器Timer,代码如下:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'dart:async';
import 'bloc_time.dart';
///Bloc 初探
class TestBlocTimePage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _TestABPageState();
}
}
class _TestABPageState extends State {
///计时器
Timer _timer;
@override
void initState() {
super.initState();
///间隔1秒执行时间
_timer= Timer.periodic(Duration(milliseconds: 1000), (timer) {
///发送事件
BlocProvider.of<TimeCounterBloc>(context).add(0);
});
}
@override
void dispose() {
super.dispose();
///取消计时器
_timer.cancel();
}
@override
Widget build(BuildContext context) {
///页面主体脚手架
return Scaffold(
appBar: AppBar(
title: Text("Bloc "),
),
body:buildBlocBuilder(),
);
}
///代码清单1-1
/// 通过 BlocBuilder 来消费事件结果
Widget buildBlocBuilder() {
return BlocBuilder<TimeCounterBloc, String>(
builder: (context, time) {
///在这里 time 就是BloC回传的数据处理结果
///当然在这里是一个 String 类型
return Container(
///外边距
margin: EdgeInsets.only(left: 12,top: 12),
child: Text(
'$time',
style: TextStyle(fontSize: 22.0, color: Colors.red),
),
);
},
);
}
}
在这里定义的 BlocBuilder,本文第三小节有分析。
定义的 Bloc 角色,代码如下:
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:intl/intl.dart';
///Bolc 的泛型数据类型
///在这里 int 代表输入的事件类型
/// String 代表输出的数据结果
class TimeCounterBloc extends Bloc<int, String> {
///默认构造
///[initialState]默认的数据
TimeCounterBloc(String initialState) : super(initialState);
///业务逻辑处理 [event] 事件标识
@override
Stream<String> mapEventToState(int event) async* {
///获取当前的时间
DateTime dateTime= DateTime.now();
///格式化时间 import 'package:intl/intl.dart';
///需要添加 intl 依赖
String formatTime = DateFormat("HH:mm:ss").format(dateTime);
///发射更新数据
yield formatTime;
}
}
3 BlocBuilder
BlocBuilder与StreamBuilder的作用一样,用来消费事件结果,就是显示数据结果,它的构建构建如下:
class BlocBuilder<C extends Cubit<S>, S> extends BlocBuilderBase<C, S> {
/// {@macro bloc_builder}
const BlocBuilder({
Key key,
@required this.builder,
C cubit,
BlocBuilderCondition<S> buildWhen,
}) : assert(builder != null),
super(key: key, cubit: cubit, buildWhen: buildWhen);
... ...
}
builder 参数为必选参数,用来构建消费的 UI 视图,它需要一个 BlocWidgetBuilder,BlocWidgetBuilder定义如下:
typedef BlocWidgetBuilder<S> = Widget Function(BuildContext context, S state);
BlocWidgetBuilder 的入参数二 state 就是 BloC 中发射的数据。
buildWhen参数,用于向BlocBuilder提供可选的条件,返回 true,那么将调用state执行视图的重新构建,如果返回false,则不会执行视图的重建操作。
Widget buildBlocBuilder() {
return BlocBuilder<TimeCounterBloc, String>(
///条件判断是否更新视图
/// 参数 previous 上一次的数据
/// 参数 current 当前的数据
buildWhen: (String previous,String current){
print("previous $previous current $current");
return true;
},
///入参 time 为BloC发射的数据
builder: (context, time) {
///在这里 time 就是BloC回传的数据处理结果
///当然在这里是一个 String 类型
return Container(
///外边距
margin: EdgeInsets.only(left: 12,top: 12),
child: Text(
'$time',
style: TextStyle(fontSize: 22.0, color: Colors.red),
),
);
},
);
}
4 BlocProvider
BlocProvider相当于一个组合者,它将 Bloc 、事件、消费组合在一起,它是一个组件。
可以通过BlocProvider.of (context)向其子级提供bloc,如上述的 add 方法发送事件
BlocProvider.of<TimeCounterBloc>(context).add(0);
5 MultiBlocProvider
MultiBlocProvider是一个用于将多个BlocProvider合并为一个BlocProvider的组件。
MultiBlocProvider(
providers: [
BlocProvider<BlocA>(
create: (BuildContext context) => BlocA(),
),
BlocProvider<BlocB>(
create: (BuildContext context) => BlocB(),
),
BlocProvider<BlocC>(
create: (BuildContext context) => BlocC(),
),
],
child: 子页面视图,
)
然后在子页面中 通过 BlocBuilder 分别引用不同的 Bloc 就可以,小编这也有 Demo 点击查看详情
完毕
以小编的性格,要实现百万Demo随时复制粘贴肯定是需要源码的
当然以小编的性格,肯定是要有视频录制的,目前正在录制中,你可以关注一下 西瓜视频 --- 早起的年轻人 随后会上传
- 一则数据库无法重启的案例分析(r8笔记第96天)
- 最大公约数和最小公倍数及其应用(Go语言解法)
- JAVA private私有类的 默认构造函数 的生成过程
- 一次数据变更的审核过程(r8笔记第95天)
- JavaScript 学习一
- 与Ajax同样重要的jQuery(2)
- 寻找第K元素的八大算法、源码及拓展
- 索引优先队列-IndexedPrirotyQueue的原理及实现(源码)
- Java 集合系列02之 Collection架构
- 开发者需要掌握的JS事件
- Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例
- Kosaraju算法、Tarjan算法分析及证明--强连通分量的线性算法
- 关于curl网站运维与开发的那些事
- 并查集Union-find及其在最小生成树中的应用
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Maven 打包涉及证书文件问题
- maven 安装alipay-sdk包到本地及远程仓库
- maven 基础 maven-shade-pluginMaven Scopepom.xml 样例
- zookeeper应用:屏障、队列、分布式锁
- Java AIO 异步IO应用实例
- Java NIO 同步非阻塞应用实例
- Spring Boot 示例项目
- Jetty 发布web服务
- Netty 异步的、事件驱动的网络应用程序框架和工具
- Consul 服务发现和配置
- Consul 启动命令,Web UI
- Thrift 跨服务开发框架
- Java并发之BlockingQueue 阻塞队列(ArrayBlockingQueue、LinkedBlockingQueue、DelayQueue、PriorityBlockingQueue、Sy
- Java并发之CountDownLatch 多功能同步工具类
- Java并发之CyclicBarrier 可重用同步工具类