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
相关产品推荐
相关产品推荐

