Flutter:如何将List<curso>存入SharedPreferences并读取展示?
一、修改保存逻辑(支持添加多个课程到收藏列表)
当前代码仅能保存单个课程对象,要实现列表存储,需先读取已有收藏列表,添加新对象后再整体保存:
void saveCourseFavSP(String title,String entidad,String categoria,String emision,String imgcourse,String urlcourse,String idioma,String duracion,String description) async { SharedPreferences cursosFav = await SharedPreferences.getInstance(); // 创建新的课程对象 final newCurso = curso( title: title, entidad: entidad, categoria: categoria, emision: emision, imgcourse: imgcourse, urlcourse: urlcourse, idioma: idioma, duracion: duracion, description: description, ); // 读取已有的收藏列表JSON String? existingJson = cursosFav.getString('coursesFavorites'); List<Map<String, dynamic>> coursesList = []; if (existingJson != null) { // 将已有JSON解析为Map列表 coursesList = List<Map<String, dynamic>>.from(jsonDecode(existingJson)); } // 可选:检查课程是否已存在,避免重复添加 bool isExist = coursesList.any((courseMap) => courseMap['title'] == title); if (!isExist) { // 将新课程转为Map加入列表 coursesList.add(newCurso.toMap()); // 保存更新后的列表JSON cursosFav.setString('coursesFavorites', jsonEncode(coursesList)); print("课程已添加到收藏"); } else { print("该课程已在收藏列表中"); } }
二、修改加载逻辑(读取整个收藏列表)
调整加载方法,将保存的列表JSON解析为List<curso>对象:
Future<List<curso>> loadDataCursosFavSP() async { SharedPreferences cursosFav = await SharedPreferences.getInstance(); String? json = cursosFav.getString("coursesFavorites"); if (json == null) { print("收藏列表为空"); return []; } else { // 解析JSON为动态列表 List<dynamic> jsonList = jsonDecode(json); // 将每个Map转为curso对象 List<curso> coursesList = jsonList.map((map) => curso.fromMap(map)).toList(); print("成功加载${coursesList.length}个收藏课程"); return coursesList; } }
三、在ListView中展示收藏列表
使用FutureBuilder处理异步加载,配合ListView.builder渲染列表:
class FavoritesScreen extends StatefulWidget { const FavoritesScreen({super.key}); @override State<FavoritesScreen> createState() => _FavoritesScreenState(); } class _FavoritesScreenState extends State<FavoritesScreen> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("我的收藏课程")), body: FutureBuilder<List<curso>>( future: loadDataCursosFavSP(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } else if (snapshot.hasError) { return Center(child: Text("加载失败: ${snapshot.error}")); } else if (!snapshot.hasData || snapshot.data!.isEmpty) { return const Center(child: Text("暂无收藏课程")); } else { return ListView.builder( itemCount: snapshot.data!.length, itemBuilder: (context, index) { curso course = snapshot.data![index]; return ListTile( leading: Image.network(course.imgcourse, width: 50, height: 50, fit: BoxFit.cover), title: Text(course.title), subtitle: Text("机构: ${course.entidad} | 时长: ${course.duracion}"), // 可根据需求添加点击事件或更多展示内容 ); }, ); } }, ), ); } }
四、关键注意事项
- 列表维护逻辑:不能直接覆盖单个对象,必须先读取已有列表数据,添加新对象后再整体保存
- 去重处理:可通过课程唯一标识(如
title)判断是否已存在,根据业务需求调整规则 - 异步状态处理:加载数据为异步操作,需用
FutureBuilder或在initState中预加载数据后更新状态 - JSON转换规则:保存时先将每个
curso转为Map,再将Map列表转为JSON字符串;读取时反向解析即可
内容的提问来源于stack exchange,提问作者Carlos Peñaranda
相关产品推荐
相关产品推荐

