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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 17:39:22