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

Flutter中如何缓存多选下拉框选中项并在返回应用时预填充

Flutter中如何缓存多选下拉框选中项并在返回应用时预填充

我仔细看了你的代码和遇到的问题,你碰到的Lookup failed: SharedPreferences错误主要是因为重复获取SharedPreferences实例、RxList赋值逻辑的小问题,再加上回调里的一些疏漏,咱们一步步来解决:

1. 修复SharedPreferences实例重复获取的问题

你的QuestionnaireController已经通过构造函数拿到了preferences实例,但在loadSelectedChoices方法里又重新调用await SharedPreferences.getInstance(),这不仅多余,还可能导致实例冲突引发查找失败。直接用控制器里已有的实例即可:

Future<void> loadSelectedChoices() async {
  // 移除重复的实例获取代码
  // SharedPreferences prefs = await SharedPreferences.getInstance();
  List<String>? loadedChoices = preferences.getStringList('selected_choices');
  if (loadedChoices != null) {
    print("loading choices");
    print(choices.value);
    // 用assignAll更新已有RxList的内容,而非创建新实例
    choices.assignAll(loadedChoices);
  }
}

2. 修正RxList的赋值逻辑

之前你用choices.value = loadedChoices.obs;,这相当于给choices赋值了一个新的RxList实例,会导致原有的UI监听绑定失效。改用assignAll更新已有RxList的内容,能保证UI正确响应数据变化。

3. 优化回调中的异步保存逻辑

onItemAdded和onItemRemoved回调里调用异步方法是可行的,但要确保saveSelectedChoices正确使用已有的preferences实例,并且加上await保证保存操作完成:

Future<void> saveSelectedChoices() async {
  print("saving");
  // 直接使用成员变量的preferences实例
  await preferences.setStringList('selected_choices', choices.toList());
  print(choices.toList());
}

4. 修复自定义Chip的删除逻辑

在_customChoice的ChiponDeleted回调里,你直接操作selectedItems是无效的——这个列表是DropdownSearch传递的副本,应该直接操作控制器里的choices并触发保存:

onDeleted: () {
  // 直接操作控制器的choices列表
  controller.choices.remove(e);
  // 调用保存方法同步到本地存储
  controller.saveSelectedChoices();
},

5. 修复FocusNode的内存泄漏问题

你在_buildDropdownSearch里每次build都会创建新的FocusNode,这会导致内存泄漏。把它移到_MyHomePageState的成员变量中,并在页面销毁时清理:

class _MyHomePageState extends State<MyHomePage> {
  // 将FocusNode定义为组件成员变量
  late FocusNode _dropdownFocusNode;
  
  final dropdownSearchTheme = ThemeData(...);

  @override
  void initState() {
    super.initState();
    _dropdownFocusNode = FocusNode();
    // 统一在这里添加监听逻辑
    _dropdownFocusNode.addListener(() {
      final controller = Get.find<QuestionnaireController>();
      controller.showBackButton.value = _dropdownFocusNode.hasFocus ? false : true;
    });
  }

  @override
  void dispose() {
    // 销毁FocusNode,避免内存泄漏
    _dropdownFocusNode.dispose();
    super.dispose();
  }

  // 在_buildDropdownSearch中直接使用这个成员变量
  Widget _buildDropdownSearch(...) {
    final controller = Get.find<QuestionnaireController>();
    // 移除这里的FocusNode创建代码
    // FocusNode _dropdownFocusNode = FocusNode();
    // ... 其他代码
    popupProps: PopupPropsMultiSelection.bottomSheet(
      searchFieldProps: TextFieldProps(
        // ...
        focusNode: _dropdownFocusNode,
      ),
      // ...
    ),
  }
}

完成这些修改后,你再测试应用:选中选项后退出再打开,选中项会被预填充;添加/删除选项时数据也会正确保存到本地,不会再出现SharedPreferences查找失败的错误。

备注:内容来源于stack exchange,提问作者Gladiator

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 15:54:54