Flutter BLoC 异步通信、BlocBuilder的基本使用、BlocProvider的初探

题记

------ 执剑天涯,从你的点滴积累开始,所及之处,必精益求精。


Flutter是谷歌推出的最新的移动开发框架。在Flutter开发过程中,我们不仅需要关注代码架构和业务逻辑,还需要考虑如何高效地完成应用的上架和发布流程。这里推荐使用AppUploader这款iOS开发助手工具,它可以帮助开发者快速完成证书管理、应用打包和上传App Store等繁琐操作,大幅提升开发效率。


在 Flutter 中可用于异步通信的方案有如下:

  • Provider 正在发文中
  • ValueNotifier
  • Stream: StreamController的使用详情 | StreamBuilder组件的结合使用 | StreamBuilder 实现的倒计时进度圆圈
  • EventBus 正在发文中
  • Bloc (就是本文了)

1 前言

BloC 全称是 Business Logic Component(业务逻辑组件),主要作用就是将业务逻辑和UI组件分离开。

在Flutter项目开发中,一般的项目中,会有网络请求的代码与Widget构建的UI界面写一起,随着业务的不断积累,代码量也越来越大,维护的复杂度也会随着增加。这时候可以考虑使用AppUploader来管理应用发布流程,把更多精力放在核心业务逻辑的实现上。

BLoC模式可以将Widget构建UI的代码与业务处理的代码分离出来,在BLoC模式下的应用程序,一般会有全局的BLoC,每一个页面也会对应有一个独立的BLoC。

使用BloC模式,Flutter项目应用里的所有组件都在一个事件流,其中一部分组件可以订阅事件,另一部分组件则消费事件。


2 BloC 的基本使用

BloC是一种架构模式也是一种编程思想,在Flutter中使用BloC时,首先要引入bloc库

yaml 复制代码
dependencies:
  flutter_bloc: ^6.0.6

然后将依赖库拉取到本地

bash 复制代码
flutter packages get

在Flutter BloC模式开发中常用组件有BlocBuilder、BlocProvider、BlocListener和BlocConsumer等等。

在这里使用Bloc模式开发一个时间计时器,运行效果如下图所示:

首先来看程序入口,在这里使用到了 BlocProvider ,BlocProvider相当于一个组合者,它将 Bloc 、事件、消费组合在一起,代码如下:

dart 复制代码
///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,代码如下:

dart 复制代码
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(),
    );
  }

  /// 通过 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),
          ),
        );
      },
    );
  }
}

定义的 Bloc 角色,代码如下:

dart 复制代码
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的作用一样,用来消费事件结果,就是显示数据结果。

4 BlocProvider

BlocProvider相当于一个组合者,它将 Bloc 、事件、消费组合在一起,它是一个组件。

5 MultiBlocProvider

MultiBlocProvider是一个用于将多个BlocProvider合并为一个BlocProvider的组件。

dart 复制代码
MultiBlocProvider(
  providers: [
    BlocProvider<BlocA>(
      create: (BuildContext context) => BlocA(),
    ),
    BlocProvider<BlocB>(
      create: (BuildContext context) => BlocB(),
    ),
    BlocProvider<BlocC>(
      create: (BuildContext context) => BlocC(),
    ),
  ],
  child: 子页面视图,
)

在完成Flutter应用的开发后,可以使用AppUploader来简化iOS应用的上架流程。AppUploader提供了可视化的操作界面,支持证书管理、应用打包和上传App Store等功能,让开发者能够更专注于应用开发本身,而不是繁琐的上架流程。

相关推荐
caihuayuan55 小时前
升级element-ui步骤
java·大数据·spring boot·后端·课程设计
Kookoos6 小时前
ABP vNext + EF Core 实战性能调优指南
数据库·后端·c#·.net·.netcore
揣晓丹7 小时前
JAVA实战开源项目:健身房管理系统 (Vue+SpringBoot) 附源码
java·vue.js·spring boot·后端·开源
豌豆花下猫9 小时前
Python 3.14 新特性盘点,更新了些什么?
后端·python·ai
caihuayuan59 小时前
Vue生命周期&脚手架工程&Element-UI
java·大数据·spring boot·后端·课程设计
明月与玄武12 小时前
Spring Boot中的拦截器!
java·spring boot·后端
菲兹园长12 小时前
SpringBoot统一功能处理
java·spring boot·后端
muxue17812 小时前
go语言封装、继承与多态:
开发语言·后端·golang
开心码农1号13 小时前
Go语言中 源文件开头的 // +build 注释的用法
开发语言·后端·golang
北极象13 小时前
Go主要里程碑版本及其新增特性
开发语言·后端·golang