Flutter如何实现选中答案颜色持久化 重启APP仍保留状态?

问题说明
我希望用户选中答案后,对应选项的颜色状态可以持久保存,即便关闭应用再次打开也能保留。我尝试使用sharedPreferences实现但失败了,不清楚问题出在哪里,以下是我的原始代码:
class Answers extends StatefulWidget { final List questionAnswers; Answers(this.questionAnswers); @override _AnswersState createState() => _AnswersState(); } class _AnswersState extends State<Answers> { var isSelected = false; void onTap() { setState(() { isSelected = true; }); } @override Widget build(BuildContext context) { return Column( children: [ ...widget.questionAnswers.map((answer) { return InkWell( onTap: onTap, child: Container( padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 10), margin: const EdgeInsets.only(bottom: 8, left: 10, right: 12), decoration: BoxDecoration( color: isSelected ? answer["isCorrect"] ? Colors.green.shade200 : Colors.red.shade200 : Colors.transparent, borderRadius: BorderRadius.circular(10), border: Border.all( color: Colors.grey.shade400, ), ), child: Row( children: [ Text("${answer["code"]})"), SizedBox(width: 10), Text(answer["answerText"]), ], ), ), ); }).toList(), ], ); } }
问题分析
- 原始代码中
isSelected是全局布尔变量,所有选项共用同一个状态,点击任意选项会触发所有选项同时变色,无法区分单个选项的选中状态 - 没有实现状态的持久化读写逻辑,选中状态仅存在于内存中,应用重启后就会丢失
解决方案
首先在pubspec.yaml中添加shared_preferences依赖:
dependencies: flutter: sdk: flutter shared_preferences: ^2.2.2
修改后的完整代码如下:
import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; class Answers extends StatefulWidget { final List questionAnswers; // 传入题目唯一标识,用来区分不同题目的选中状态 final String questionId; const Answers(this.questionAnswers, {super.key, required this.questionId}); @override _AnswersState createState() => _AnswersState(); } class _AnswersState extends State<Answers> { // 存储已选中的答案code,区分不同选项的选中状态 Set<String> selectedAnswerCodes = {}; late SharedPreferences prefs; @override void initState() { super.initState(); _loadSelectedState(); } // 初始化时从SharedPreferences读取已保存的选中状态 Future<void> _loadSelectedState() async { prefs = await SharedPreferences.getInstance(); final savedCodes = prefs.getStringList('selected_${widget.questionId}'); if (savedCodes != null) { setState(() { selectedAnswerCodes = savedCodes.toSet(); }); } } // 选中选项时更新状态并保存到SharedPreferences void onTap(String answerCode) { setState(() { // 单选逻辑:选中新选项后清空之前的选中状态,需要多选可以删掉clear逻辑 selectedAnswerCodes.clear(); selectedAnswerCodes.add(answerCode); }); prefs.setStringList('selected_${widget.questionId}', selectedAnswerCodes.toList()); } @override Widget build(BuildContext context) { return Column( children: [ ...widget.questionAnswers.map((answer) { final isSelected = selectedAnswerCodes.contains(answer["code"]); return InkWell( onTap: () => onTap(answer["code"]), child: Container( padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 10), margin: const EdgeInsets.only(bottom: 8, left: 10, right: 12), decoration: BoxDecoration( color: isSelected ? answer["isCorrect"] ? Colors.green.shade200 : Colors.red.shade200 : Colors.transparent, borderRadius: BorderRadius.circular(10), border: Border.all( color: Colors.grey.shade400, ), ), child: Row( children: [ Text("${answer["code"]})"), const SizedBox(width: 10), Text(answer["answerText"]), ], ), ), ); }).toList(), ], ); } }
调用示例
Answers(yourQuestionAnswersList, questionId: "question_001")
传入对应题目的唯一ID即可,选中状态会和对应题目绑定,重启应用后也能正常读取之前的选中状态,单个选项的选中状态不会互相干扰。
内容的提问来源于stack exchange,提问作者Mohammad Sami
相关产品推荐
相关产品推荐

