Flutter使用shared_preferences添加单条列表项重复报错求解
问题原因
- 缺少
dart:convert依赖导入:jsonEncode、jsonDecode方法来自该库,未导入时会触发类型不支持的报错。 - 列表重复累加:
getUser()读取本地缓存数据前未清空原有listItems列表,每次触发读取都会在现有列表基础上重复追加已存在数据;saveData()每次执行都全量读取本地缓存追加新值,未和内存中已有状态做同步,进一步放大重复问题。 - 逻辑错误:
saveData()中date字段写死为字符串'date',没有实际使用获取到的当前时间;jsonDecode错误传入刚创建的Map对象而非编码后的字符串,属于参数传递错误;代码末尾存在多余的闭合大括号,会触发语法报错。 - 异步逻辑不规范:将SharedPreferences的异步写入操作放在
setState内部执行,会导致状态更新时序异常。
修复后完整代码
import 'dart:async'; import 'dart:convert'; // 补全缺失的convert库导入 import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return const MaterialApp( title: 'SharedPreferences Demo', home: Test(), ); } } class Test extends StatefulWidget { const Test({Key? key}) : super(key: key); @override State<Test> createState() => _TestState(); } class _TestState extends State<Test> { List<Map<String, dynamic>> listItems = []; List<String> cart = []; saveData() async { DateTime now = DateTime.now(); // 构造包含brand和date字段的新条目 final Map<String, dynamic> newItem = { 'brand': 'item', 'date': now.toString(), // 存入实际的当前时间 }; SharedPreferences prefs = await SharedPreferences.getInstance(); List<String> storedCart = prefs.getStringList("cart") ?? []; // 追加新条目到缓存列表 storedCart.add(jsonEncode(newItem)); // 执行持久化写入 await prefs.setStringList("cart", storedCart); // 更新内存状态刷新UI setState(() { cart = storedCart; listItems.add(newItem); }); } getUser() async { SharedPreferences prefs = await SharedPreferences.getInstance(); List<String> storedCart = prefs.getStringList("cart") ?? []; setState(() { // 读取前先清空旧列表,避免数据重复累加 listItems.clear(); cart = storedCart; for (String itemStr in storedCart) { listItems.add(jsonDecode(itemStr)); } }); } @override void initState() { super.initState(); getUser(); } @override Widget build(BuildContext context) { return Scaffold( body: Column( children: <Widget>[ Expanded( child: listItems.isNotEmpty ? ListView.builder( itemCount: listItems.length, itemBuilder: buildList) : const Center( child: Text('EMPTY LIST'), )), Center( child: FloatingActionButton( onPressed: saveData, tooltip: 'Increment', child: const Icon(Icons.add), ), ) ], ), ); } Widget buildList(BuildContext context, int index) { return Container( margin: const EdgeInsets.all(4), decoration: BoxDecoration( border: Border.all( color: Colors.black, width: 2, ), borderRadius: BorderRadius.circular(5)), child: ListTile( title: Text(listItems[index]['brand']), subtitle: Text(listItems[index]['date'] ?? "null"), ), ); } }
修复说明
- 补全了缺失的
dart:convert导入,解决json序列化/反序列化的类型报错。 - 读取本地缓存时先清空列表旧数据,从根源解决条目重复累加的问题。
- 修正了新条目构造逻辑,
date字段实际存储当前时间字符串,移除了错误的jsonDecode传参。 - 把SharedPreferences异步操作移到
setState外部执行,保证状态更新时序正确。 - 删除了原代码末尾多余的闭合大括号,修复语法错误。
- 移除了类中未被使用的冗余
item全局变量,精简代码。
内容的提问来源于stack exchange,提问作者Majkelele
相关产品推荐
相关产品推荐

