Flutter Bloc继承Equatable后仅可单次页面跳转问题解决方案问询
问题根因
你遇到的跳转限制本质是Bloc的状态去重逻辑和Equatable的相等判断规则共同导致的:
- Equatable通过
props属性判断两个实例是否相等,你当前定义的OpeningSecondPageState和MainInitial的props都是空数组,所有同类型的实例都会被判定为完全相等。 - 第一次触发跳转事件后,Bloc的当前状态就停留在
OpeningSecondPageState,第二次再触发事件emit同一个状态时,Bloc检测到前后状态相等,就会丢弃新状态不会通知listener,自然不会触发第二次跳转。 - 不继承Equatable时,Dart默认按内存地址判断实例相等,每次emit的新实例都被判定为不同状态,所以可以多次触发跳转。
解决方案
不需要修改第二页逻辑,有两种常用的可行方案:
方案1:导航触发后立即切回初始状态(更推荐)
导航本身是一次性事件,不需要作为持久状态保存,emit导航状态后立即切回初始状态即可,修改Bloc的事件处理逻辑:
// 修改main_bloc.dart中的OpenSecondPageEvent处理逻辑 on<OpenSecondPageEvent>((event, emit) { emit(OpeningSecondPageState()); emit(MainInitial()); });
优点:符合状态设计规范,不需要修改原有状态定义,性能开销极小。
方案2:给导航状态添加唯一标识
如果有场景需要保留导航状态,可以给OpeningSecondPageState添加唯一参数到props中,保证每次emit的状态都被判定为不同实例:
// 修改main_bloc.dart中的OpeningSecondPageState定义 class OpeningSecondPageState extends MainState { // 用时间戳作为唯一标识,也可以替换为随机数等其他唯一值 final DateTime triggerTime; OpeningSecondPageState(): triggerTime = DateTime.now(); @override List<Object> get props => [triggerTime]; }
优点:不需要调整事件处理逻辑,适合需要保留导航触发记录的场景。
两种方案修改完成后,都可以实现每次点击按钮正常跳转第二页,返回后再次点击仍然生效的效果,同时保留Equatable继承不影响Bloc测试编写。
内容的提问来源于stack exchange,提问作者preckrasno
相关产品推荐
相关产品推荐

