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

Flutter中如何动态替换/添加Shared Preferences存储的现有数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 13:20:28