Flutter中Bloc结合showDialog报错:无法识别Widget树中的Bloc
问题根源
Dialog的Widget树是挂载在应用根节点的Overlay上的,和当前ListScreen的Widget树完全独立。所以哪怕ListScreen能通过自身上下文拿到Bloc,Dialog也继承不到这个上下文,自然找不到对应的Bloc实例。
解决办法
给Dialog单独包裹BlocProvider.value
调用showDialog时,用ListScreen的上下文先拿到Bloc,再在Dialog的外层套BlocProvider.value把Bloc传进去:showDialog( context: context, // 必须用ListScreen的上下文,不能用Dialog内部的context builder: (dialogCtx) { return BlocProvider.value( value: BlocProvider.of<GateInBloc>(context), child: AlertDialog( content: BlocBuilder<GateInBloc, GateInState>( builder: (ctx, state) { // 这里就能正常访问Bloc状态了 return Text(state.toString()); }, ), ), ); }, );提前缓存Bloc实例
也可以在ListScreen的方法里先把Bloc实例取出来,再传入Dialog的BlocProvider.value:// 在触发Dialog的方法里先获取Bloc final gateInBloc = context.read<GateInBloc>(); // 用read比of更简洁 showDialog( context: context, builder: (dialogCtx) { return BlocProvider.value( value: gateInBloc, child: YourCustomSearchDialog(), ); }, );
为什么其他地方正常?
- ListScreen的
initState和AppBar第一个IconButton用的都是ListScreen的上下文,属于同一个Widget树,能直接找到BlocProvider。 - 主体部分的
ConsumerBloc也是依托ListScreen的上下文,自然能拿到Bloc。只有Dialog跳出了这个上下文范围,才会出现找不到Bloc的错误。
内容的提问来源于stack exchange,提问作者Dat Minh
相关产品推荐
相关产品推荐

