如何改造MycarsCubit添加状态,实现加载指示器显示与错误处理?
解决方案
1. 完善状态类(state文件)
扩展MycarsState,新增加载、加载完成、错误三种状态,覆盖不同业务场景:
abstract class MycarsState {} // 初始状态:未加载或清空后的初始状态 class MycarsInitial extends MycarsState { final String number; final String type; MycarsInitial({required this.number, required this.type}); } // 加载状态:正在获取数据时触发 class MycarsLoading extends MycarsState {} // 加载完成状态:数据成功获取后触发,携带有效数据 class MycarsLoaded extends MycarsState { final String number; final String type; MycarsLoaded({required this.number, required this.type}); } // 错误状态:数据获取失败时触发,携带错误信息 class MycarsError extends MycarsState { final String errorMessage; MycarsError({required this.errorMessage}); }
2. 修改Cubit类(bloc文件)
更新MycarsCubit,添加数据获取逻辑,并在对应流程中emit不同状态,同时优化状态管理逻辑(不再在Cubit中单独存储数据,统一通过状态传递):
class MycarsCubit extends Cubit<MycarsState> { MycarsCubit() : super(const MycarsInitial(number: '', type: '')); // 模拟异步获取数据(实际场景替换为真实API请求) Future<void> fetchCarsData() async { emit(MycarsLoading()); // 触发加载状态,显示加载指示器 try { // 模拟API请求延迟 await Future.delayed(const Duration(seconds: 2)); // 假设获取到的车辆数据 final fetchedNumber = '京A12345'; final fetchedType = '轿车'; // 加载成功,触发完成状态 emit(MycarsLoaded(number: fetchedNumber, type: fetchedType)); } catch (e) { // 加载失败,触发错误状态 emit(MycarsError(errorMessage: e.toString())); } } // 更新车辆信息 void change({required String numberText, required String typeText}) { emit(MycarsLoaded(number: numberText, type: typeText)); } // 清空车辆信息 void clear() { emit(const MycarsInitial(number: '', type: '')); } }
3. UI层根据状态渲染对应内容
使用BlocBuilder监听状态变化,针对不同状态展示对应UI:
BlocBuilder<MycarsCubit, MycarsState>( builder: (context, state) { if (state is MycarsLoading) { // 加载状态:显示圆形加载指示器 return const Center(child: CircularProgressIndicator()); } else if (state is MycarsError) { // 错误状态:显示错误提示 return Center(child: Text('加载失败:${state.errorMessage}')); } else if (state is MycarsLoaded) { // 加载完成:展示车辆信息 return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('车牌号:${state.number}'), const SizedBox(height: 10), Text('车辆类型:${state.type}'), const SizedBox(height: 20), ElevatedButton( onPressed: () => context.read<MycarsCubit>().clear(), child: const Text('清空信息'), ), ], ); } else { // 初始状态:显示触发加载的按钮 return Center( child: ElevatedButton( onPressed: () => context.read<MycarsCubit>().fetchCarsData(), child: const Text('获取车辆数据'), ), ); } }, )
核心说明
- 状态职责单一:每个状态对应唯一的业务场景,避免状态混淆
- 数据统一管理:所有业务数据通过状态传递,Cubit不再单独存储,保证状态一致性
- 流程闭环:从触发加载到成功/失败,每个环节都有对应的状态反馈,UI能及时响应
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

