You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中多Bloc通信及单页面多Bloc实现(Bloc 8.0)

Flutter 单页面多 Bloc 实现(Bloc 8.0+)

1. 添加依赖

在pubspec.yaml中引入所需包:

dependencies:
  flutter:
    sdk: flutter
  bloc: ^8.1.0
  flutter_bloc: ^8.1.3
  equatable: ^2.0.5 # 简化状态/事件的相等性判断逻辑

2. 实现 FirstBloc(独立业务逻辑)

定义事件与状态

import 'package:equatable/equatable.dart';
import 'package:bloc/bloc.dart';

// FirstBloc 事件
abstract class FirstEvent extends Equatable {
  const FirstEvent();
  @override
  List<Object> get props => [];
}

class FirstIncrement extends FirstEvent {}
class FirstDecrement extends FirstEvent {}

// FirstBloc 状态
class FirstState extends Equatable {
  final int count;
  const FirstState({required this.count});
  factory FirstState.initial() => const FirstState(count: 0);
  @override
  List<Object> get props => [count];
}

// FirstBloc 核心逻辑
class FirstBloc extends Bloc<FirstEvent, FirstState> {
  FirstBloc() : super(FirstState.initial()) {
    on<FirstIncrement>((event, emit) => emit(FirstState(count: state.count + 1)));
    on<FirstDecrement>((event, emit) => emit(FirstState(count: state.count - 1)));
  }
}

3. 实现 SecondBloc(独立业务逻辑)

定义事件与状态

import 'package:equatable/equatable.dart';
import 'package:bloc/bloc.dart';

// SecondBloc 事件
abstract class SecondEvent extends Equatable {
  const SecondEvent();
  @override
  List<Object> get props => [];
}

class SecondAddText extends SecondEvent {
  final String text;
  const SecondAddText(this.text);
  @override
  List<Object> get props => [text];
}

class SecondClearText extends SecondEvent {}

// SecondBloc 状态
class SecondState extends Equatable {
  final String content;
  const SecondState({required this.content});
  factory SecondState.initial() => const SecondState(content: "");
  @override
  List<Object> get props => [content];
}

// SecondBloc 核心逻辑
class SecondBloc extends Bloc<SecondEvent, SecondState> {
  SecondBloc() : super(SecondState.initial()) {
    on<SecondAddText>((event, emit) => emit(SecondState(content: state.content + event.text)));
    on<SecondClearText>((event, emit) => emit(SecondState.initial()));
  }
}

4. 实现 CombinedBloc(监听合并状态)

定义合并状态与核心逻辑

import 'package:equatable/equatable.dart';
import 'package:bloc/bloc.dart';

// 合并后的状态
class CombinedState extends Equatable {
  final int firstCount;
  final String secondContent;
  const CombinedState({required this.firstCount, required this.secondContent});
  factory CombinedState.initial() => const CombinedState(firstCount: 0, secondContent: "");
  @override
  List<Object> get props => [firstCount, secondContent];
}

// 监听First/SecondBloc并生成合并状态
class CombinedBloc extends Bloc<Object, CombinedState> {
  final FirstBloc firstBloc;
  final SecondBloc secondBloc;
  late final StreamSubscription _firstSub;
  late final StreamSubscription _secondSub;

  CombinedBloc({required this.firstBloc, required this.secondBloc}) : super(CombinedState.initial()) {
    // 订阅FirstBloc状态变化
    _firstSub = firstBloc.stream.listen((state) {
      emit(CombinedState(firstCount: state.count, secondContent: this.state.secondContent));
    });
    // 订阅SecondBloc状态变化
    _secondSub = secondBloc.stream.listen((state) {
      emit(CombinedState(firstCount: this.state.firstCount, secondContent: state.content));
    });
  }

  @override
  Future<void> close() {
    _firstSub.cancel();
    _secondSub.cancel();
    return super.close();
  }
}

5. 页面UI(动态响应所有Bloc状态)

使用MultiBlocProvider统一管理Bloc,通过BlocBuilder监听状态更新:

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class MultiBlocPage extends StatelessWidget {
  const MultiBlocPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MultiBlocProvider(
      providers: [
        BlocProvider(create: (_) => FirstBloc()),
        BlocProvider(create: (_) => SecondBloc()),
        BlocProvider<CombinedBloc>(
          create: (ctx) => CombinedBloc(
            firstBloc: ctx.read<FirstBloc>(),
            secondBloc: ctx.read<SecondBloc>(),
          ),
        ),
      ],
      child: Scaffold(
        appBar: AppBar(title: const Text("多Bloc示例")),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              // 展示FirstBloc状态
              BlocBuilder<FirstBloc, FirstState>(
                builder: (ctx, state) => Text(
                  "First计数: ${state.count}",
                  style: const TextStyle(fontSize: 18),
                ),
              ),
              Row(
                children: [
                  ElevatedButton(
                    onPressed: () => context.read<FirstBloc>().add(FirstIncrement()),
                    child: const Text("+1"),
                  ),
                  const SizedBox(width: 12),
                  ElevatedButton(
                    onPressed: () => context.read<FirstBloc>().add(FirstDecrement()),
                    child: const Text("-1"),
                  ),
                ],
              ),
              const SizedBox(height: 32),
              // 展示SecondBloc状态
              BlocBuilder<SecondBloc, SecondState>(
                builder: (ctx, state) => Text(
                  "Second内容: ${state.content.isEmpty ? "空" : state.content}",
                  style: const TextStyle(fontSize: 18),
                ),
              ),
              Row(
                children: [
                  ElevatedButton(
                    onPressed: () => context.read<SecondBloc>().add(const SecondAddText("测试 ")),
                    child: const Text("添加文本"),
                  ),
                  const SizedBox(width: 12),
                  ElevatedButton(
                    onPressed: () => context.read<SecondBloc>().add(SecondClearText()),
                    child: const Text("清空"),
                  ),
                ],
              ),
              const SizedBox(height: 32),
              // 展示合并后的状态
              BlocBuilder<CombinedBloc, CombinedState>(
                builder: (ctx, state) => Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    const Text("合并状态:", style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
                    Text("计数: ${state.firstCount} | 内容: ${state.secondContent.isEmpty ? "空" : state.secondContent}"),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

核心说明

  • 状态联动:CombinedBloc通过订阅First/SecondBloc的状态流,实现任一子Bloc状态变化时自动更新合并状态
  • UI响应:每个BlocBuilder仅监听对应Bloc的状态,状态变更时精准重建组件,避免不必要的UI刷新
  • 资源管理:CombinedBloc在close方法中取消订阅,彻底避免内存泄漏

内容的提问来源于stack exchange,提问作者Muhammad Bilal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 03:37:16