flutter之bloc使用详解

flutter中一切皆为Widget,因此在我们开发中,往往业务和UI逻辑写在一起,这样不利于代码维护,因此状态管理框架久诞生了,这篇就开始讲一讲Bloc。

对于Bloc库有两个,如下图:
flutter_bloc其实是对bloc的进一步封装,flutter_bloc引入了bloc库和provider库,是对bloc的进一步延伸。

bloc官方文档:https://bloclibrary.dev/#/zh-cn/coreconcepts

一.Bloc介绍

BLoC设计模式:BLoC模式的核心是Sink和Stream,它们用于处理输入和输出。通常,你会创建一个BLoC类,该类接收输入流并根据输入产生输出流。然后,UI组件订阅输出流以接收状态更新,并将用户操作发送到输入流。

Bloc有两种模式:

Bloc模式:该模式划分四层结构

bloc:逻辑层

state:数据层

event:所有的交互事件

view:页面

Cubit模式:该模式划分了三层结构

cubit:逻辑层

state:数据层

view:页面

Bloc模式和Cubit模式区别:

  • 复杂度: BLoC:BLoC通常用于管理更复杂的业务逻辑和状态。它可以处理多个事件和多个状态,适用于大型、复杂的应用程序。

    Cubit:Cubit的设计更简单,适用于处理较简单的状态和事件。它更适合于小型和中型应用程序,以及对状态管理模式不太熟悉的开发者。

  • 事件和状态管理: BLoC:在BLoC中,事件和状态是分开管理的,你需要自己编写事件和状态的类,并在BLoC中进行映射。这使得BLoC更加灵活,但也更加复杂。

    Cubit:Cubit将事件和状态合并到一个类中,称为Cubit类。这使得代码更加简洁,但在处理复杂的事件和状态时可能会变得混乱。

  • 异步支持: BLoC:BLoC天生支持异步操作,可以轻松处理异步任务,例如网络请求。这是因为BLoC的mapEventToState方法可以返回Stream。

    Cubit:Cubit也支持异步操作,但需要使用Emit函数来发射新的状态。

二.flutter_bloc简单使用

导入库:

dart 复制代码
flutter_bloc: ^8.1.3

这是一个插件,可选择使用,简化模版代码生成。安装flutter_bloc插件

使用案例:计数器

dart 复制代码
import 'package:flutter_bloc/flutter_bloc.dart';

// 定义事件
enum CounterEvent { increment, decrement }

class CounterBloc extends Bloc<CounterEvent, int> {
  CounterBloc() : super(0);

  @override
  Stream<int> mapEventToState(CounterEvent event) async* {
    switch (event) {
      case CounterEvent.increment:
        yield state + 1;
        break;
      case CounterEvent.decrement:
        yield state - 1;
        break;
    }
  }
}

在页面中使用 Bloc:

dart 复制代码
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class CounterPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Counter App'),
      ),
      body: BlocProvider(
        create: (context) => CounterBloc(),
        child: CounterView(),
      ),
    );
  }
}

class CounterView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final counterBloc = BlocProvider.of<CounterBloc>(context);

    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          BlocBuilder<CounterBloc, int>(
            builder: (context, count) {
              return Text('Count: $count', style: TextStyle(fontSize: 24));
            },
          ),
          SizedBox(height: 16),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              FloatingActionButton(
                onPressed: () {
                  counterBloc.add(CounterEvent.increment);
                },
                child: Icon(Icons.add),
              ),
              SizedBox(width: 16),
              FloatingActionButton(
                onPressed: () {
                  counterBloc.add(CounterEvent.decrement);
                },
                child: Icon(Icons.remove),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

三.各种小部件

BlocBuilder

dart 复制代码
BlocBuilder<BlocA, BlocAState>(
  builder: (context, state) {
    // return widget here based on BlocA's state
  }
)

BlocBuilder是一个 Flutter 小部件,需要一个bloc和 一个builder函数。BlocBuilder处理构建小部件以响应新状态。BlocBuilder与 非常相似,StreamBuilder但具有更简单的 API,以减少所需的样板代码量。该builder函数可能会被多次调用,并且应该是一个纯函数,它返回一个小部件以响应状态。

BlocSelector

dart 复制代码
BlocSelector<BlocA, BlocAState, SelectedState>(
  selector: (state) {
    // return selected state based on the provided state.
  },
  builder: (context, state) {
    // return widget here based on the selected state.
  },
)

BlocSelector是一个 Flutter 小部件,它类似于BlocBuilder但允许开发人员通过基于当前块状态选择新值来过滤更新。如果所选值不更改,则会阻止不必要的构建。所选值必须是不可变的,以便BlocSelector准确确定是否builder应该再次调用。

BlocListener

dart 复制代码
BlocListener<BlocA, BlocAState>(
  listener: (context, state) {
    // do stuff here based on BlocA's state
  },
  child: Container(),
)

BlocListener是一个 Flutter 小部件,它采用BlocWidgetListener和 一个可选参数bloc,并调用listener来响应块中的状态变化。它应该用于每次状态更改需要发生一次的功能,例如导航、显示 a SnackBar、显示 aDialog等...

相关推荐
耳東陈1 小时前
Flutter开箱即用一站式解决方案-新增企业级日志
flutter
顾林海1 小时前
Flutter 图片组件全面解析:从基础加载到高级应用
android·前端·flutter
眼镜会飞1 小时前
Flutter window和Mac中webview2使用Cef替代
windows·flutter·mac
淡写成灰1 小时前
Flutter自定义带有Badger组件组
flutter
好的佩奇2 小时前
Dart 之任务
android·flutter·dart
豪冷啊15 小时前
Flutter Invalid constant value.
flutter
顾林海19 小时前
Flutter容器组件深度解析
android·前端·flutter
xq952719 小时前
mac os flutter 配置环境变量
flutter
sg_knight1 天前
Flutter性能优化终极指南:从JIT到AOT的深度调优
前端·flutter·性能优化·web·dart
zonda的地盘1 天前
[Get 源码] GetPageRoute 与 GetxController 的自动回收机制
flutter