48Flutter_Bloc 异步通信基本使用

Flutter_Bloc 异步通信基本使用

1.简介

Bloc全称是 Business Logic Component(业务逻辑组件),主要作用就是将UI视图与数据逻辑处理分割开来。Bloc用法以及功能上与谷歌官方提供的Provider基本一致,二者差异较小,与Android中ViewModel作用类似, 在构建MVVM时,该层主要是分离业务逻辑,VM层。在BLoC模式下的应用程序,一般会有全局的BLoC,每一个页面也会对应有一个独立的BLoC

572421986474d7c60cdc01f6c5852ade.png

2基本使用

1.了解原理

7ae95a6d43709570cd0469f5b18c03ef.png

  • Bloc为中间逻辑层,与Android中ViewModel一致

  • BlockBuilder:消费或者说监听,与provider中Consumer一致,类似于LiveData的监听

  • BlocObserver:进行事件观察的接口

  • BlocProvider:可通过BlocProvider.of (context)向其子级提bloc。它被作为依赖项注入(DI)部件(widget),以便可以将一个bloc的单个实例提供给子树中的多个部件(widgets)。

  • BlocListener:监听状态

  • RepositoryProvider:

    之前开发过APP的同学可能用过Repository模式,就是将APP中的数据需求抽取成Repository接口,可以根据不同的数据源来定义不同的实现,比如LocalRepository和NetRepository,通过代理来得到最终的Repository实现。通常会把Repository作为单例来让全局共享数据。数据缓存本来就是很占内存的,如果使用单例会导致内存利用效率不高。
    Bloc也对数据的共享也做了支持,可以更好的控制数据仓库的生命周期。RepositoryProvider就是这样的控件,可以将存储库的单个实例提供给子树中的多个部件(widgets)。RepositoryProvider不需要指定泛型类型,只用指定create方法和child结点即可。

说明:BlocProvider,如果在APP页面的home节点开始创建,所有子控件都能拿到

依赖:

  flutter_bloc: 7.0.0
2.发送事件
BlocProvider.of<TimeCounterBloc>(context).add(0);
3.发送数据
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:intl/intl.dart';
class TimeCounterBloc extends Bloc<int, String> {
  TimeCounterBloc(String initialState) : super(initialState);

  ///业务逻辑处理 [event] 事件标识
  @override
  Stream<String> mapEventToState(int event) async* {
    DateTime dateTime= DateTime.now();
    String formatTime = DateFormat("HH:mm:ss").format(dateTime);
    ///发射更新数据
    yield formatTime;
  }
}

——————通过add方法,以及event事件,来识别相应的请求,与Provider不同

4.接收数据,
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),
          ),
        );
      },
    );
5.关闭

先关闭网络耗时请求,在关闭流

  @override
  void dispose() {
    super.dispose();
    ///取消计时器
    _timer.cancel();
    BlocProvider.of<TimeCounterBloc>(context).close();
  }

代码如下:

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_first/day52Bloc/test01/TimeCounterBloc.dart';

///flutter应用程序中的入口函数
void main() => runApp(BlocMainApp());

///应用的根布局
class BlocMainApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    ///构建Materia Desin 风格的应用程序
    return BlocProvider<TimeCounterBloc>(
      create: (context) => TimeCounterBloc(""),
      child: MaterialApp(
        ///Android应用程序中任务栏中显示应用的名称
        title: "配制",
        theme: ThemeData(
          accentColor: Colors.blue,

          ///默认是 Brightness.light
          brightness: Brightness.light,
        ),

        ///默认的首页面
        home: TimePage(),
      ),
    );
  }
}

class TimePage extends StatefulWidget {
  TimePage({Key key}) : super(key: key);

  @override
  _TimePageState createState() {
    return _TimePageState();
  }
}

class _TimePageState extends State<TimePage> {
  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    BlocProvider.of<TimeCounterBloc>(context).close();
    super.dispose();
  }

  Widget buildBlocBuilder() {
    return BlocBuilder<TimeCounterBloc, String>(
      builder: (context, time) {
        return Container(
          margin: EdgeInsets.only(left: 12, top: 12),
          child: Text(
            '$time',
            style: TextStyle(fontSize: 22.0, color: Colors.red),
          ),
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        SizedBox(height: 50),
        Container(
          width: 200,
          height: 200,
          color: Colors.red,
          child: OutlinedButton(
            child: Text("bloc"),
            onPressed: () {
              BlocProvider.of<TimeCounterBloc>(context).add(0);
            },
          ),
        ),
        Container(
          margin: EdgeInsets.only(top: 10, bottom: 10),
          child: Text("点击"),
        ),
        buildBlocBuilder()
      ],
    );
  }
}

TimeCount:

import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:intl/intl.dart';
///Bolc 的泛型数据类型
///在这里 int 代表输入的事件类型
///      String 代表输出的数据结果
class TimeCount extends Bloc<int, String> {
  ///默认构造
  ///[initialState]默认的数据
  TimeCount(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;
  }

}
6MultiBlocProvider

多个BlocProvider合并为一个BlocProvider的组件,用法等价于Provider中MultiProvider

class BlocProviders extends StatelessWidget {
  BlocProviders({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MultiBlocProvider(
      providers: [
        BlocProvider<TimeCount03>(
          create: (BuildContext context) => TimeCount03("00:00:00"),
        ),
        BlocProvider<RandomCount03>(
          create: (BuildContext context) => RandomCount03("00:00:00"),
        ),
      ],
    );
  }
}
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_first/day52Bloc/Demo03/RandomCount03.dart';
import 'package:flutter_first/day52Bloc/test01/TimeCount03.dart';

import 'TimeCount03.dart';

///flutter应用程序中的入口函数
void main() => runApp(BlocMainApp());

///应用的根布局
class BlocMainApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    ///构建Materia Desin 风格的应用程序
    return BlocProvider<TimeCount03>(
      create: (context) => TimeCount03(""),
      child: MaterialApp(
        ///Android应用程序中任务栏中显示应用的名称
        title: "配制",
        theme: ThemeData(
          accentColor: Colors.blue,

          ///默认是 Brightness.light
          brightness: Brightness.light,
        ),

        ///默认的首页面
        home: TimePage(),
      ),
    );
  }
}

class BlocProviders extends StatelessWidget {
  BlocProviders({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MultiBlocProvider(
      providers: [
        BlocProvider<TimeCount03>(
          create: (BuildContext context) => TimeCount03("00:00:00"),
        ),
        BlocProvider<RandomCount03>(
          create: (BuildContext context) => RandomCount03("00:00:00"),
        ),
      ],
    );
  }
}

class TimePage extends StatefulWidget {
  TimePage({Key key}) : super(key: key);

  @override
  _TimePageState createState() {
    return _TimePageState();
  }
}

class _TimePageState extends State<TimePage> {
  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    BlocProvider.of<TimeCount03>(context).close();
    BlocProvider.of<RandomCount03>(context).close();
    super.dispose();
  }

  Widget buildBlocBuilder() {
    return BlocBuilder<TimeCount03, String>(
      builder: (context, time) {
        return Container(
          margin: EdgeInsets.only(left: 12, top: 12),
          child: Text(
            '$time',
            style: TextStyle(fontSize: 22.0, color: Colors.red),
          ),
        );
      },
    );
  }

  Widget buildBlocBuilder2() {
    return BlocBuilder<RandomCount03, String>(builder: (context, time) {
      return Container(
        margin: EdgeInsets.only(left: 12, top: 12),
        child: Text(
          '$time',
          style: TextStyle(fontSize: 22.0, color: Colors.red),
        ),
      );
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        SizedBox(height: 50),
        Container(
          width: 200,
          height: 200,
          color: Colors.red,
          child: OutlinedButton(
            child: Text("bloc"),
            onPressed: () {
              BlocProvider.of<TimeCount03>(context).add(0);
            },
          ),
        ),
        Container(
          width: 200,
          height: 200,
          color: Colors.yellow,
          child: OutlinedButton(
            child: Text("点击"),
            onPressed: () {
              BlocProvider.of<RandomCount03>(context).add(0);
            },
          ),
        ),
        buildBlocBuilder(),
        buildBlocBuilder2()
      ],
    );
  }
}

7.buildWhen

用于向BlocBuilder提供可选的条件,返回 true,那么将调用state执行视图的重新构建,如果返回false,则不会执行视图的重建操作。

回调拦截使用

      buildWhen: (String previous, String current) {
        return true;
      },
8.buildConsumer

不在解答,与provider中Consumer一致,BlocBuilder相当于provider中selector

9.RepositoryProvider

RepositoryProvider 通过RepositoryProvider.of(context)为其子项提供存储库。它使用依赖注入将存储库的单个实例提供给子树中的多个小部件。BlocProvider应该用于提供Bloc,而RepositoryProvider只能用于存储库。

RepositoryProvider(
  create: (context) => RepositoryA(),
  child: ChildA(),
);

获取,所以该种方式,可以用于页面跳转之间大量信息的传递,少数信息可以直接参数传递,数据量较大,可以通过该种方式传递

// with extensions
context.read<RepositoryA>();

// without extensions
RepositoryProvider.of<RepositoryA>(context)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值