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

Flutter RawAutocomplete的OptionsViewBuilder无法显示SnackBar求助

问题解决:RawAutocomplete中SnackBar无法弹出的问题

问题原因

RawAutocomplete的optionsViewBuilder返回的选项列表是渲染在Overlay中的,它的上下文属于独立的Widget分支,和页面的Scaffold不在同一个上下文树中。即使你在itemBuilder里添加了Builder,也无法获取到Scaffold的上下文,因此会报错Scaffold.of() called with a context that does not contain a Scaffold。

解决方案

方案1:使用GlobalKey直接获取ScaffoldState

这是最直接的解决方式,通过全局Key绕过上下文查找的限制:

  1. 在页面的State类中定义全局Key:
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
  1. 给页面的Scaffold设置这个Key:
Scaffold(
  key: _scaffoldKey,
  // 页面其他内容
)
  1. 修改点击事件中的代码,用全局Key调用SnackBar:
onTap: () {
  refreshList(
    context,
    operation: 'add',
    option,
  );
  // 显示SnackBar
  _scaffoldKey.currentState?.showSnackBar(
    SnackBar(content: Text('已选择${option.name}')),
  );
},

方案2:利用RawAutocomplete的onSelected回调(推荐)

RawAutocomplete本身提供了onSelected参数,它的上下文属于页面主Widget树,可以直接访问Scaffold,更符合Flutter的设计规范:

  1. 给RawAutocomplete添加onSelected回调:
RawAutocomplete<Product>(
  onSelected: (Product selectedProduct) {
    refreshList(
      context,
      operation: 'add',
      selectedProduct,
    );
    // 这里的context可直接获取Scaffold
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text('已选择${_displayStringForOption(selectedProduct)}')),
    );
  },
  // 原有参数保持不变
)
  1. 修改optionsViewBuilder中的GestureDetector,调用传入的onSelected:
optionsViewBuilder: (BuildContext context,
    AutocompleteOnSelected<Product> onSelected,
    Iterable<Product> options) {
  return Align(
    alignment: Alignment.topLeft,
    child: Material(
      elevation: 4.0,
      child: SizedBox(
        height: 200.0,
        child: ListView.builder(
          padding: const EdgeInsets.all(8.0),
          itemCount: options.length,
          itemBuilder: (BuildContext context, int index) {
            final Product option = options.elementAt(index);
            return GestureDetector(
              onTap: () {
                onSelected(option); // 调用全局的onSelected逻辑
              },
              child: ListTile(
                title: Text(_displayStringForOption(option) +
                    " Price Kes. ${option.price}"),
                leading: Image.network(
                  "http://192.168.1.38/ci/uploads/${option.image}",
                  errorBuilder: (context, error, stackTrace) {
                    return Image.asset("assets/images/camera.png");
                  },
                ),
              ),
            );
          },
        ),
      ),
    ),
  );
},

提示:可以去掉原来itemBuilder里的Builder,因为不再需要它来获取上下文。

额外说明

  • Flutter 2.0+版本推荐使用ScaffoldMessenger.of(context)代替Scaffold.of(context).showSnackBar,后者已被标记为过时。
  • 如果你的refreshList函数需要使用Scaffold上下文,确保传递的是页面主上下文(比如方案2中使用的context)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 15:02:06