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

Flutter应用重启后用户添加的列表元素丢失问题求助

问题描述

用户通过文本框添加的列表元素能正常渲染显示,但应用重启后,这些元素会从列表及UI中消失。


相关代码

CardData模型类

class CardData {
CardData(this.name, this.university, this.department, this.rollNumber,
  this.emailId);
final String name;
final String university;
final String department;
final String rollNumber;
final String emailId;
}

表单组件代码

import 'package:flutter/material.dart';
import 'package:student_card/models/card_data.dart';

class MyForm extends StatefulWidget {
  const MyForm({super.key, required this.onAddNewData});
  final void Function(CardData newData) onAddNewData;

  @override
  State<MyForm> createState() => _MyFormState();
}

class _MyFormState extends State<MyForm> {
  final nameController = TextEditingController();
  final universityController = TextEditingController();
  final departmentController = TextEditingController();
  final rollController = TextEditingController();
  final emailIdController = TextEditingController();

  @override
  void dispose() {
    nameController.dispose();
    universityController.dispose();
    departmentController.dispose();
    rollController.dispose();
    emailIdController.dispose();
    super.dispose();
  }

  OutlineInputBorder myfocusborder() {
    return const OutlineInputBorder(
    borderRadius: BorderRadius.all(Radius.circular(20)),
    borderSide: BorderSide(
      color: Colors.greenAccent,
      width: 3,
    ));
  }

  OutlineInputBorder myinputborder() {
    //return type is OutlineInputBorder
    return const OutlineInputBorder(
    //Outline border type for TextFeild
    borderRadius: BorderRadius.all(Radius.circular(20)),
    borderSide: BorderSide(
      color: Colors.redAccent,
      width: 3,
    ));
  }

  showUserData() {
    widget.onAddNewData(CardData(
    nameController.text,
    universityController.text,
    departmentController.text,
    rollController.text,
    emailIdController.text));
  }

  @override
  Widget build(BuildContext context) {

    return Column(
      children: [
        const SizedBox(
      height: 30,
    ),
    TextField(
      // cursorColor: Theme.of(context).colorScheme.onPrimary,
      controller: nameController,
      decoration: InputDecoration(
          label: const Text('Your Name'),
          hintText: 'Name',
          border: myinputborder(),
          focusedBorder: myfocusborder(),
          enabledBorder: myinputborder()),
    ),
    const SizedBox(
      height: 20,
    ),
    TextField(
      controller: universityController,
      decoration: InputDecoration(
          label: const Text('University Name'),
          hintText: 'University',
          border: myinputborder(),
          focusedBorder: myfocusborder(),
          enabledBorder: myinputborder()),
    ),
    const SizedBox(
      height: 20,
    ),
    TextField(
      controller: departmentController,
      decoration: InputDecoration(
          label: const Text('Your Department'),
          hintText: 'Department',
          border: myinputborder(),
          focusedBorder: myfocusborder(),
          enabledBorder: myinputborder()),
    ),
    const SizedBox(
      height: 20,
    ),
    TextField(
      controller: rollController,
      decoration: InputDecoration(
          label: const Text('Your Registration Id.'),
          hintText: 'Roll Numver',
          border: myinputborder(),
          focusedBorder: myfocusborder(),
          enabledBorder: myinputborder()),
    ),
    const SizedBox(
      height: 20,
    ),
    TextField(
      controller: emailIdController,
      decoration: InputDecoration(
          label: const Text('Your Email Id.'),
          hintText: 'Email',
          border: myinputborder(),
          focusedBorder: myfocusborder(),
          enabledBorder: myinputborder()),
    ),
    const SizedBox(
      height: 20,
    ),
    ElevatedButton(
        onPressed: () {
          showUserData();
        },
        child: const Text('Submit'))
      ],
    );
  }
}

列表及元素添加逻辑代码

import 'package:flutter/material.dart';
import 'package:student_card/Widgets/data_list.dart';
import 'package:student_card/models/card_data.dart';
import 'package:student_card/Widgets/form.dart';

class StudentCard extends StatefulWidget {
  const StudentCard({super.key});

  @override
  State<StudentCard> createState() {
    return _StudentCardState();
  }
}

class _StudentCardState extends State<StudentCard> {

  List<CardData> listData = [
    CardData('Moiz', 'UMT', 'Software', 'FA21-BEE-106', 'imoiz@gmail.com'),
  ];

  void addNewData(CardData newData) {
    setState(() {
      listData.add(newData);
    });
  }

  showFormSheet(BuildContext context) {
    showModalBottomSheet(
    isScrollControlled: true,
    context: context,
    builder: (context) {
      return Container(
        padding: const EdgeInsets.symmetric(
          horizontal: 20,
          vertical: 15,
        ),
        child: Column(
          children: [
            MyForm(
              onAddNewData: addNewData,
            )
          ],
        ),
      );
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
    title: const Text('Student Card Maker'),
    backgroundColor: const Color(0xFFC539B4),
    actions: [
      IconButton(
          onPressed: () {
            showFormSheet(context);
          },
          icon: const Icon(Icons.add))
    ],
  ),
  body: Container(
    padding: const EdgeInsets.all(10),
    child: Column(
      children: [
        const Text('The data below'),
        const SizedBox(
          height: 10,
        ),
        Expanded(
          child: DataList(data: listData),
        )
      ],
    ),
  ),
    );
  }
} 

列表项渲染组件代码

import 'package:flutter/material.dart';
import 'package:student_card/models/card_data.dart';

class CardItem extends StatelessWidget {
  const CardItem({super.key, required this.studentData});
  final CardData studentData;
  @override
  Widget build(BuildContext context) {
    // Full screen width and height
    double Width = MediaQuery.of(context).size.width;
    double height = MediaQuery.of(context).size.height;

// Height (without SafeArea)
    var padding = MediaQuery.of(context).viewPadding;
    double height1 = height - padding.top - padding.bottom;
double realHeight = 0.75 * height1;
double realWidth = 0.90 * Width;

// Height (without status bar)
// double height2 = height - padding.top;

return Container(
  height: realHeight,
  width: realWidth,
  padding: const EdgeInsets.all(5),
  child: Card(
    child: Column(
      children: [
        Text(studentData.name),
        Text(studentData.university),
        Text(studentData.department),
        Text(studentData.rollNumber),
        Text(studentData.emailId),
      ],
    ),
     ),
  ),
);
  }
}

解决方案

问题核心是当前数据仅存储在内存中,应用重启后内存被清空,数据自然丢失。需要将数据持久化到本地存储,以下是具体实现步骤:

1. 修改CardData类支持序列化

要将对象存储到本地,需先把对象转换为可存储的格式(如JSON),让CardData实现序列化和反序列化:

class CardData {
  CardData(this.name, this.university, this.department, this.rollNumber, this.emailId);

  final String name;
  final String university;
  final String department;
  final String rollNumber;
  final String emailId;

  // 转成Map用于序列化
  Map<String, dynamic> toMap() {
    return {
      'name': name,
      'university': university,
      'department': department,
      'rollNumber': rollNumber,
      'emailId': emailId,
    };
  }

  // 从Map转成CardData对象
  factory CardData.fromMap(Map<String, dynamic> map) {
    return CardData(
      map['name'] as String,
      map['university'] as String,
      map['department'] as String,
      map['rollNumber'] as String,
      map['emailId'] as String,
    );
  }
}

2. 添加shared_preferences依赖

在pubspec.yaml中添加依赖:

dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^2.2.2

执行flutter pub get完成依赖安装。

3. 修改StudentCard页面逻辑,实现数据持久化

更新_StudentCardState类,添加数据读取和保存逻辑:

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:student_card/Widgets/data_list.dart';
import 'package:student_card/models/card_data.dart';
import 'package:student_card/Widgets/form.dart';

class StudentCard extends StatefulWidget {
  const StudentCard({super.key});

  @override
  State<StudentCard> createState() {
    return _StudentCardState();
  }
}

class _StudentCardState extends State<StudentCard> {
  List<CardData> listData = [];

  @override
  void initState() {
    super.initState();
    // 页面初始化时读取本地存储的数据
    loadSavedData();
  }

  // 读取本地存储的数据
  Future<void> loadSavedData() async {
    final prefs = await SharedPreferences.getInstance();
    final savedData = prefs.getStringList('student_data');
    
    if (savedData != null) {
      setState(() {
        listData = savedData.map((jsonStr) {
          // 将JSON字符串转成Map,再转成CardData对象
          final map = Map<String, dynamic>.from(
            jsonDecode(jsonStr) as Map,
          );
          return CardData.fromMap(map);
        }).toList();
      });
    } else {
      // 如果没有数据,初始化默认数据
      setState(() {
        listData = [
          CardData('Moiz', 'UMT', 'Software', 'FA21-BEE-106', 'imoiz@gmail.com'),
        ];
        saveData(); // 保存默认数据
      });
    }
  }

  // 将数据保存到本地存储
  Future<void> saveData() async {
    final prefs = await SharedPreferences.getInstance();
    // 将每个CardData转成JSON字符串
    final jsonList = listData.map((data) {
      return jsonEncode(data.toMap());
    }).toList();
    await prefs.setStringList('student_data', jsonList);
  }

  void addNewData(CardData newData) {
    setState(() {
      listData.add(newData);
    });
    // 添加新数据后立即保存
    saveData();
  }

  showFormSheet(BuildContext context) {
    showModalBottomSheet(
      isScrollControlled: true,
      context: context,
      builder: (context) {
        return Container(
          padding: const EdgeInsets.symmetric(
            horizontal: 20,
            vertical: 15,
          ),
          child: Column(
            children: [
              MyForm(
                onAddNewData: addNewData,
              )
            ],
          ),
        );
      });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Student Card Maker'),
        backgroundColor: const Color(0xFFC539B4),
        actions: [
          IconButton(
              onPressed: () {
                showFormSheet(context);
              },
              icon: const Icon(Icons.add))
        ],
      ),
      body: Container(
        padding: const EdgeInsets.all(10),
        child: Column(
          children: [
            const Text('The data below'),
            const SizedBox(
              height: 10,
            ),
            Expanded(
              child: DataList(data: listData),
            )
          ],
        ),
      ),
    );
  }
} 

说明

  • 通过shared_preferences将数据以JSON字符串列表的形式存储在本地,应用重启时会从本地读取数据并恢复列表。
  • 每次添加新数据后都会调用saveData()方法,确保数据及时持久化。
  • 如果需要更复杂的本地操作(如查询、删除),可考虑使用Hive或SQLite等数据库方案。

内容的提问来源于stack exchange,提问作者Muhammad fahad azam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 22:45:54