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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 05:45:03