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

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

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


Flutter是谷歌推出的最新的移动开发框架。

【x1】微信公众号的每日提醒 随时随记 每日积累 随心而过

【x2】各种系列的视频教程 免费开源 关注 你不会迷路

【x3】系列文章 百万 Demo 随时 复制粘贴 使用


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


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随时复制粘贴肯定是需要源码的

当然以小编的性格,肯定是要有视频录制的,目前正在录制中,你可以关注一下 西瓜视频 --- 早起的年轻人 随后会上传

相关文章
|
iOS开发
Flutter与iOS原生通信方式
Flutter与iOS原生通信方式
480 2
|
27天前
|
存储 开发者
Flutter&鸿蒙next 使用 BLoC 模式进行状态管理详解
本文详细介绍了如何在 Flutter 中使用 BLoC 模式进行状态管理。BLoC 模式通过将业务逻辑与 UI 层分离,利用 Streams 和 Sinks 实现状态管理和 UI 更新,提高代码的可维护性和可测试性。文章涵盖了 BLoC 的基本概念、实现步骤及代码示例,包括定义 Event 和 State 类、创建 Bloc 类、提供 Bloc 实例以及通过 BlocBuilder 更新 UI。通过一个简单的计数器应用示例,展示了 BLoC 模式的具体应用和代码实现。
73 1
|
3月前
|
JSON Dart Java
flutter开发多端平台应用的探索 下 (跨模块、跨语言通信之平台通道)
flutter开发多端平台应用的探索 下 (跨模块、跨语言通信之平台通道)
|
5月前
|
安全 Shell Android开发
Flutter和Native 通信 pigeon
Flutter和Native 通信 pigeon
|
5月前
|
Dart Android开发 Windows
Flutter和Native 通信 android端
Flutter和Native 通信 android端
|
7月前
|
开发框架 前端开发 Android开发
【Flutter 前端技术开发专栏】Flutter 与原生模块通信机制
【4月更文挑战第30天】本文探讨了Flutter作为跨平台开发框架与原生Android和iOS交互的必要性,主要通过方法调用和事件传递实现。文中详细介绍了Flutter与Android/iOS的通信方式,数据传输(包括基本和复杂类型),性能优化,错误处理以及实际应用案例。理解并掌握这一通信机制对开发高质量移动应用至关重要,未来有望随着技术发展得到进一步优化。
78 0
【Flutter 前端技术开发专栏】Flutter 与原生模块通信机制
|
7月前
|
存储 UED 开发者
Flutter的状态管理:setState、Provider、Bloc的使用详解
【4月更文挑战第26天】Flutter状态管理详解:涵盖setState基础,Provider的跨组件共享及Bloc的复杂场景处理。了解这三种方法的优缺点,助力优化应用数据一致性与用户体验。当状态管理需求升级,从简单的setState到Provider的便利,再到Bloc的强大功能,开发者可根据项目规模和复杂度选择合适策略。
|
API 开发者
一文带你快速入门Flutter通信channel
Flutter中的通信channel是指Flutter和原生平台之间进行通信的渠道,主要包括basicMessageChannel、MethodChannel和EventChannel等。
一文带你快速入门Flutter通信channel
|
Dart 监控 Java
Flutter和原生代码的通信
我们只用Flutter实现了一个页面,现有的大量逻辑都是用Java实现,在运行时会有许多场景必须使用原生应用中的逻辑和功能,例如网络请求
Flutter和原生代码的通信