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等功能,让开发者能够更专注于应用开发本身,而不是繁琐的上架流程。

相关推荐
零零壹1110 分钟前
什么是 Redis?为什么你应该关心它?
vue.js·后端·面试
喵手17 分钟前
同事突然考我1000 个线程同时运行,怎么防止不卡?
java·后端·java ee
玄明Hanko19 分钟前
你的 DDD 还在纸上谈兵?是时候落地了!
java·后端·领域驱动设计
一介输生20 分钟前
Spring Boot 实现权限管理(上)
java·后端
喵手21 分钟前
为什么用了 Stream,代码反而越写越丑了?
java·后端·java ee
flzjkl22 分钟前
【Java并发】【ArrayBlockingQueue】适合初学体质的ArrayBlockingQueue入门
java·后端
flzjkl25 分钟前
【源码】【Java并发】【ArrayBlockingQueue】适合中学者体质的ArrayBlockingQueue
java·后端
讳疾忌医_note25 分钟前
为何 C++ 多态设计总出错?大部份开发者没掌握的虚函数底层逻辑
后端
努力的搬砖人.40 分钟前
搭建一个Spring Boot聚合项目
java·spring boot·后端
林太白1 小时前
Nest如何连接数据库
前端·后端·node.js