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
相关产品推荐
相关产品推荐

