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

Flutter中showModalBottomSheet结合Bloc出现Provider查找失败问题

解决Flutter Bloc在showModalBottomSheet中找不到Provider的问题

错误原因

你遇到的问题有两个核心原因:

  1. 点击「应用」按钮时使用的context是showModalBottomSheet的builder函数上下文,这个上下文位于你新建的BlocProvider<ProductsBloc>上层,无法访问到Bloc实例。
  2. 更关键的是,你当前在BottomSheet中新建了一个独立的ProductsBloc实例,这会导致筛选操作无法同步更新原页面的产品数据——你应该和原页面共享同一个Bloc实例。

解决方案

方案一:共享原页面的Bloc实例(推荐)

通过BlocProvider.value将原页面的ProductsBloc实例传递给BottomSheet,确保筛选操作能作用于同一个Bloc:

// 调用showFilter的上下文必须在ProductsBloc的Provider范围内
showFilter(BuildContext context) => showModalBottomSheet(
    context: context,
    backgroundColor: Colors.white,
    isScrollControlled: true,
    builder: (context) {
      return BlocProvider.value(
        // 获取原页面的Bloc实例并传递
        value: context.read<ProductsBloc>(),
        child: Container(
          padding: REdgeInsets.symmetric(horizontal: 8, vertical: 12),
          height: MediaQuery.of(context).size.height * 0.9,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              // 保留原有筛选组件代码
              Row(
                children: [
                  Text(
                    'Фильтр',
                    style: TextStyles.bodyStyle,
                  ),
                  const Spacer(),
                  IconButton(
                      onPressed: () {
                        Navigator.pop(context);
                      },
                      icon: const Icon(Icons.close)),
                ],
              ),
              SizedBox(height: 10.h),
              // ...其余筛选Dropdown组件...
              const Spacer(),
              ElevatedButton(
                  onPressed: () {
                    // 现在能正确访问到共享的Bloc实例
                    context.read<ProductsBloc>().add(LoadProductsWithFilter());
                    Navigator.pop(context);
                  },
                  child: const Text('Применить')),
            ],
          ),
        ),
      );
    });

注意:确保调用showFilter的上下文(即AppBar所在页面的context)已经被BlocProvider<ProductsBloc>包裹,比如原页面结构如下:

BlocProvider(
  create: (context) => ProductsBloc(),
  child: YourProductPage(), // 包含AppBar的页面
)

方案二:在BottomSheet内新建Bloc(不推荐)

如果确实需要在BottomSheet内使用独立的Bloc,需要通过Builder组件获取BlocProvider内部的上下文来读取实例:

showFilter(BuildContext context) => showModalBottomSheet(
    context: context,
    backgroundColor: Colors.white,
    isScrollControlled: true,
    builder: (context) {
      return BlocProvider<ProductsBloc>(
        create: (context) => ProductsBloc(),
        child: Container(
          padding: REdgeInsets.symmetric(horizontal: 8, vertical: 12),
          height: MediaQuery.of(context).size.height * 0.9,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              // 保留原有筛选组件代码
              // ...其余筛选Dropdown组件...
              const Spacer(),
              // 用Builder获取BlocProvider内部的上下文
              Builder(
                builder: (innerContext) {
                  return ElevatedButton(
                      onPressed: () {
                        innerContext.read<ProductsBloc>().add(LoadProductsWithFilter());
                        Navigator.pop(context);
                      },
                      child: const Text('Применить'));
                },
              ),
            ],
          ),
        ),
      );
    });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 10:05:39