Flutter跨页面数据追踪:健身APP数据传递及存储咨询
问题解答
一、传递完整训练数据的方案可行性
你的Map<String, List>方案是可行的,但更推荐定义自定义数据类来封装训练信息,类型更安全、代码可读性更高,也能避免字符串键名写错的低级错误:
- 先定义训练和动作的数据类:
// 训练动作类,根据你的需求添加字段(比如组数、次数等) class Exercise { final String name; final int sets; final int reps; Exercise({required this.name, required this.sets, required this.reps}); } // 训练计划类,包含名称和动作列表 class Workout { final String name; final List<Exercise> exercises; Workout({required this.name, required this.exercises}); }
- 在添加页面点击确认时,返回完整的
Workout对象:
// 添加页面确认按钮的逻辑 Navigator.pop(context, Workout( name: _workoutNameController.text, exercises: _collectedExercises, // 你收集到的训练动作列表 ));
- 主页面接收并处理完整数据:
// 主页面跳转至添加页面的逻辑 final result = await Navigator.push( context, MaterialPageRoute(builder: (context) => AddWorkoutPage()), ); if (result is Workout) { setState(() { _workoutList.add(result); // 将完整训练数据加入列表 }); }
二、新手友好的数据存储方案
1. 初期开发:内存缓存(最简便)
直接在主页面维护一个List<Workout>变量,用来临时保存所有训练数据。重启APP后数据会丢失,但适合快速开发和功能验证,完全不需要额外依赖:
List<Workout> _workoutList = [];
2. 持久化存储:shared_preferences(新手首选)
如果需要重启APP后保留数据,shared_preferences是最容易上手的轻量级存储插件:
- 先在
pubspec.yaml添加依赖:
dependencies: flutter: sdk: flutter shared_preferences: ^2.2.2
- 将自定义对象转成JSON字符串存储/读取:
import 'dart:convert'; import 'package:shared_preferences/shared_preferences.dart'; // 保存训练列表到本地 Future<void> saveWorkouts(List<Workout> workouts) async { final prefs = await SharedPreferences.getInstance(); // 将Workout列表转成JSON字符串 final jsonStr = jsonEncode(workouts.map((w) => { 'name': w.name, 'exercises': w.exercises.map((e) => { 'name': e.name, 'sets': e.sets, 'reps': e.reps, }).toList(), }).toList()); await prefs.setString('saved_workouts', jsonStr); } // 从本地加载训练列表 Future<List<Workout>> loadWorkouts() async { final prefs = await SharedPreferences.getInstance(); final jsonStr = prefs.getString('saved_workouts'); if (jsonStr == null) return []; final jsonList = jsonDecode(jsonStr) as List; return jsonList.map((item) => Workout( name: item['name'], exercises: (item['exercises'] as List).map((e) => Exercise( name: e['name'], sets: e['sets'], reps: e['reps'], )).toList(), )).toList(); }
- 在主页面初始化时加载数据:
@override void initState() { super.initState(); _loadSavedWorkouts(); } Future<void> _loadSavedWorkouts() async { final workouts = await loadWorkouts(); setState(() { _workoutList = workouts; }); }
3. 进阶方案:Hive或sqflite
如果后续你的数据结构变得复杂(比如需要频繁查询、修改单个训练),可以考虑Hive(轻量NoSQL,支持直接存储自定义对象,无需JSON转换)或sqflite(SQLite数据库),但新手先从shared_preferences入门即可。
内容的提问来源于stack exchange,提问作者Piombo4
相关产品推荐
相关产品推荐

