Flutter SharedPreferences返回上一页数据无法实时更新
问题根因
你的代码存在两个核心问题,直接导致返回时数据不刷新、存储数据异常:
- 页面生命周期逻辑错误:Register页面的变量仅在初始化时读取了一次SharedPreferences数据,通过
Navigator.push跳转到AddUser页面再pop返回时,Register页面的State始终保存在导航栈中,不会重新执行初始化逻辑,自然不会主动读取最新数据触发刷新。你看到切到其他页面再回来才刷新,本质是那个时候页面触发了重建才重新读了数据。 - SharedPreferences工具类存在低级key错误:
setChurch、setChurchCity、setChurchState三个存值方法,全部错误使用了_gender作为存储key,会导致这三个字段的数据反复覆盖gender字段存储位置,后续调用对应get方法根本拿不到正确值。
修复方案
1. 先修复工具类的存储key错误
将三个set方法的key替换为对应常量,修复后代码如下:
static Future setChurch(String church) async => await _preferences.setString(_church, church); static Future setChurchCity(String churchCity) async => await _preferences.setString(_churchCity, churchCity); static Future setChurchState(String churchState) async => await _preferences.setString(_churchState, churchState);
2. 调整Register页面逻辑,监听页面返回事件刷新数据
将跳转AddUser的逻辑改为异步等待,页面pop返回后主动读取最新存储数据,通过setState触发界面刷新。同时将读取用户数据的逻辑抽为公共方法,初始化和返回时都可复用,修复后的Register页State代码如下:
class _RegisterState extends State<Register> { String? name; String? age; String? gender; String? church; String? churchCity; String? churchState; // 统一加载本地存储的用户数据 void _loadSavedUserData() { setState(() { name = UserSimplePreferences.getName(); age = UserSimplePreferences.getAge(); gender = UserSimplePreferences.getGender(); church = UserSimplePreferences.getChurch(); churchCity = UserSimplePreferences.getChurchCity(); churchState = UserSimplePreferences.getChurchState(); }); } @override void initState() { super.initState(); // 页面首次初始化加载数据 _loadSavedUserData(); } @override Widget build(BuildContext context) { return Scaffold( body: Container( child: Column( children: [ Card(child: Text(name ?? '')), Card(child: Text(age ?? '')), Card(child: Text(gender ?? '')), Card(child: Text(church ?? '')), Card(child: Text(churchCity ?? '')), Card(child: Text(churchState ?? '')), ], ), ), floatingActionButton: FloatingActionButton( backgroundColor: Colors.indigo[900], onPressed: () async { // 等待AddUser页面关闭返回 await Navigator.push( context, MaterialPageRoute(builder: (_) => AddUser(idUser: '')), ); // 返回后重新加载最新数据刷新界面 _loadSavedUserData(); }, child: Icon(Icons.add, color: Colors.white), ), ); } }
可选优化:如果不想返回时再读一次本地存储,也可以在AddUser页面保存完成后,用
Navigator.pop(context, 新存储的用户数据)把新数据直接通过路由返回值传给Register页面,直接用返回值刷新,性能更好,当前方案是对你现有代码改动最小的实现。
内容的提问来源于stack exchange,提问作者ashish rana
相关产品推荐
相关产品推荐

