Flutter中如何动态替换/添加Shared Preferences存储的现有数据
先纠正你之前的判断逻辑错误
你写的if( pref.getString('week_key') != null || pref.getString('week_key') != '')存在逻辑漏洞:只要其中一个条件成立就会执行分支,当值为null时,!= ''成立;当值为空字符串时,!= null成立,导致该条件永远为true,这也是退出登录后考勤表无法正常查看的原因。正确的判断应该是用&&表示“不为null且不为空字符串”:
if(pref.getString('week_key') != null && pref.getString('week_key') != '')
需求B:直接用新数据替换Shared Preferences现有数据(推荐方案,解决旧数据干扰问题)
每次调用getTimeSheet获取新周数据后,直接将新数据序列化并覆盖Shared Preferences中对应key的旧数据,保证存储的永远是最新的目标周数据。
实现代码
import 'package:shared_preferences/shared_preferences.dart'; import 'dart:convert'; // 保存新考勤数据,直接替换旧数据 Future<void> saveLatestTimeSheet(List<Map<String, dynamic>> newData) async { final pref = await SharedPreferences.getInstance(); // 将考勤数据转为JSON字符串存储 String jsonData = jsonEncode(newData); // 覆盖原有key对应的数据 await pref.setString('week_key', jsonData); } // 调用getTimeSheet获取数据的逻辑示例 void getTimeSheet() async { // 模拟接口请求获取新周考勤数据 List<Map<String, dynamic>> newTimeSheetData = await fetchTimeSheetFromApi(); // 保存新数据,替换旧数据 await saveLatestTimeSheet(newTimeSheetData); // 更新界面展示新数据 setState(() { yourTimeSheetList = newTimeSheetData; }); }
加载数据时的逻辑
读取数据时直接解析即可,无需复杂判断,即使存储为空也可以处理成空列表:
Future<List<Map<String, dynamic>>> loadTimeSheet() async { final pref = await SharedPreferences.getInstance(); String? jsonData = pref.getString('week_key'); if(jsonData != null && jsonData.isNotEmpty) { return List<Map<String, dynamic>>.from(jsonDecode(jsonData)); } return []; }
需求A:将新数据添加到Shared Preferences中(保留历史数据场景)
如果需要保留所有历史周的考勤数据,建议用周标识作为key,将所有数据存储为一个Map结构,每次新增数据时添加到Map中。
实现代码
import 'package:shared_preferences/shared_preferences.dart'; import 'dart:convert'; // 生成唯一的周标识(例如2023-W06,表示2023年第6周) String generateWeekIdentifier(DateTime targetDate) { int weekOfYear = targetDate.weekOfYear; return '${targetDate.year}-W$weekOfYear'; } // 添加新周数据到Shared Preferences Future<void> addTimeSheetData(String weekId, List<Map<String, dynamic>> newData) async { final pref = await SharedPreferences.getInstance(); String? existingData = pref.getString('all_time_sheets'); // 初始化存储的Map结构 Map<String, dynamic> allTimeSheets = {}; if(existingData != null && existingData.isNotEmpty) { allTimeSheets = jsonDecode(existingData); } // 添加新周数据 allTimeSheets[weekId] = newData; // 保存更新后的所有数据 await pref.setString('all_time_sheets', jsonEncode(allTimeSheets)); } // 调用getTimeSheet的逻辑示例 void getTimeSheet(DateTime targetWeekDate) async { String weekId = generateWeekIdentifier(targetWeekDate); List<Map<String, dynamic>> newTimeSheetData = await fetchTimeSheetFromApi(targetWeekDate); await addTimeSheetData(weekId, newTimeSheetData); // 更新界面 setState(() { yourTimeSheetList = newTimeSheetData; }); }
加载指定周数据的逻辑
Future<List<Map<String, dynamic>>> loadTimeSheetByWeek(String weekId) async { final pref = await SharedPreferences.getInstance(); String? existingData = pref.getString('all_time_sheets'); if(existingData != null && existingData.isNotEmpty) { Map<String, dynamic> allTimeSheets = jsonDecode(existingData); if(allTimeSheets.containsKey(weekId)) { return List<Map<String, dynamic>>.from(allTimeSheets[weekId]); } } return []; }
内容的提问来源于stack exchange,提问作者Casually Need Help
相关产品推荐
相关产品推荐

