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

Flutter Quiz应用点击答题按钮后无法切换下一题如何解决

Flutter Quiz应用点击按钮不切换下一题修复方案

Quiz应用界面截图

问题核心原因

代码中每次调用Quiz()都会生成一个全新的Quiz类实例,不同实例的内部状态(_counter计数器、题目列表)完全独立:

  • 界面渲染题目时调用Quiz().getQuestion(),拿到的是新创建的实例,_counter始终为初始值0,永远显示第一题
  • 按钮点击时执行的答案判断、nextQuestion()切题逻辑,操作的都是临时新建的Quiz实例,修改的计数器状态不会同步到界面渲染使用的实例上,因此题目不会切换。
    除此之外原有代码未做答题边界判断,答完所有题目后会触发数组越界报错,修复时可一并处理。

修复方案

核心修改点:在组件状态中初始化唯一的Quiz全局实例,所有获取题目、判断答案、切换题目的操作都基于这个实例执行,禁止零散调用Quiz()创建新对象;同时给Quiz类增加答题结束判断、重置方法,避免越界。

1. 修改main.dart代码

import 'package:flutter/material.dart';
import 'list.dart';

void main() {
  runApp(
    const Quizzler(),
  );
}

class Quizzler extends StatefulWidget {
  const Quizzler({Key? key}) : super(key: key);

  @override
  State<Quizzler> createState() => _QuizzlerState();
}

class _QuizzlerState extends State<Quizzler> {
  List<Widget> scoreKeeper = [];
  // 初始化全局唯一Quiz实例
  final Quiz quiz = Quiz();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.black,
        body: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Expanded(
              flex: 6,
              child: Padding(
                padding: const EdgeInsets.all(32.0),
                child: Center(
                  child: Text(
                    quiz.getQuestion(),
                    style: const TextStyle(
                      color: Colors.white,
                      fontSize: 20,
                    ),
                    textAlign: TextAlign.center,
                  ),
                ),
              ),
            ),
            boolButton(Colors.green, 'True'),
            boolButton(Colors.red, 'False'),
            Row(
              children: scoreKeeper,
            ),
          ],
        ),
      ),
    );
  }

  Expanded boolButton(Color c, String s) {
    return Expanded(
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: ElevatedButton(
          style: ButtonStyle(
            backgroundColor: MaterialStateProperty.all(c),
          ),
          onPressed: () {
            // 答完所有题后不再响应点击
            if (quiz.isFinished()) return;
            setState(
              () {
                switcher(s);
                quiz.nextQuestion();
                // 答完最后一题弹出结束提示
                if (quiz.isFinished()) {
                  Future.delayed(Duration.zero, () {
                    showDialog(
                      context: context,
                      builder: (context) => AlertDialog(
                        title: const Text('答题结束'),
                        content: const Text('已完成所有题目'),
                        actions: [
                          TextButton(
                            onPressed: () {
                              setState(() {
                                quiz.reset();
                                scoreKeeper.clear();
                              });
                              Navigator.pop(context);
                            },
                            child: const Text('重新开始'),
                          )
                        ],
                      ),
                    );
                  });
                }
              },
            );
          },
          child: Text(s),
        ),
      ),
    );
  }

  switcher(String s) {
    if (quiz.getAnswer().toLowerCase() == s.toLowerCase()) {
      scoreKeeper.add(
        const Icon(
          Icons.check,
          color: Colors.green,
        ),
      );
    } else {
      scoreKeeper.add(
        const Icon(
          Icons.close,
          color: Colors.red,
        ),
      );
    }
  }
}

2. 修改list.dart代码

import 'question.dart';

class Quiz {
  int _counter = 0;

  final List<Question> _q = [
    Question(
      'Cows can only be lead up a flight of stairs and not down.',
      'False',
    ),
    Question(
      'Approximately one quarter of human bones are in the feet.',
      'True',
    ),
    Question(
      'A slug\'s blood is green.',
      'True',
    ),
  ];

  void nextQuestion() {
    // 未到最后一题时才递增计数器,避免数组越界
    if (_counter < _q.length - 1) {
      _counter++;
    }
  }

  // 判断是否答完所有题目
  bool isFinished() {
    return _counter >= _q.length - 1;
  }

  // 重置题目到第一题
  void reset() {
    _counter = 0;
  }

  String getQuestion() {
    return _q[_counter].question;
  }

  String getAnswer() {
    return _q[_counter].answer;
  }
}

3. question.dart无需修改,保持原有代码即可

class Question {
  String question;
  String answer;
  Question(this.question, this.answer);
}

修复后效果

  • 点击True/False按钮后,除了正确添加得分图标,题目会自动切换到下一道
  • 答完所有3道题后会弹出答题结束提示,点击重新开始可清空答题记录回到第一题
  • 不会出现数组越界的运行时错误

内容的提问来源于stack exchange,提问作者user16746875

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 11:06:33