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

Flutter开发:如何让DropdownButton选中值跨页面持久保留?

解决方案

你的问题核心原因是:仅在选择区号时做了本地存储,但页面初始化时未读取已存储的选中值,页面重建/跳转返回后变量重置为初始空值,导致下拉框值丢失。

必改步骤(无需引入额外依赖)

  1. 调整数据加载逻辑,在国家区号JSON加载完成后,读取本地存储的选中值赋值给_selectedCountryCode,同时增加默认值避免空值报错:
// 修改你的loadJsonData方法
loadJsonData() async {
  String data = await rootBundle.loadString('assets/country_code.json');
  jsonResult = json.decode(data);
  // 新增:读取已存储的区号
  SharedPreferences prefs = await SharedPreferences.getInstance();
  String? savedCode = prefs.getString('_selectedCountryCode');
  setState(() {
    // 无存储值时默认选中马来西亚+60,可自行修改默认值
    _selectedCountryCode = savedCode ?? "+60";
  });
}
  1. 删减冗余代码:你当前onChanged回调里重复调用了两次setState和两次存储操作,保留一份即可,避免不必要的性能消耗:
onChanged: (val) async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  // 只保留StatefulBuilder的setState更新弹窗内状态即可,当前页面的变量赋值和存储写一次就够
  setStateSTB(() {
    _selectedCountryCode = val;
    prefs.setString('_selectedCountryCode', _selectedCountryCode!);
  });
  // 同步更新当前页面状态
  setState(() {});
},
  1. 增加空值兼容:渲染Dropdown时判断jsonResult是否加载完成、_selectedCountryCode是否有值,避免加载过程中出现报错:
// 在DropdownButton外层加个判断
child: jsonResult.isNotEmpty && _selectedCountryCode != null 
  ? DropdownButton(/* 原有代码 */) 
  : const CircularProgressIndicator(),

跨页面通用方案(多页面需要展示选中区号时用)

如果多个页面都需要用到该选中的国家区号,建议引入全局状态管理(以GetX为例,Provider等其他方案逻辑同理):

  1. 定义全局控制器统一管理国家数据和选中值:
import 'package:get/get.dart';
import 'package:flutter/services.dart';
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';

class CountryCodeController extends GetxController {
  String? selectedCode;
  List countryList = [];

  @override
  void onInit() {
    super.onInit();
    initData();
  }

  initData() async {
    // 加载本地国家数据
    String data = await rootBundle.loadString('assets/country_code.json');
    countryList = json.decode(data);
    // 读取存储的选中值
    SharedPreferences prefs = await SharedPreferences.getInstance();
    selectedCode = prefs.getString('_selectedCountryCode') ?? "+60";
    update();
  }

  saveSelectedCode(String code) async {
    selectedCode = code;
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setString('_selectedCountryCode', code);
    update();
  }
}
  1. 在main.dart中全局注册控制器:
void main() {
  Get.put(CountryCodeController());
  runApp(const MyApp());
}
  1. 所有页面使用时直接读取控制器中的值,修改时调用saveSelectedCode方法即可全局同步:
// 读取值
final controller = Get.find<CountryCodeController>();
// Dropdown的value赋值为controller.selectedCode
// 选择后调用controller.saveSelectedCode(val)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 01:15:06