Flutter Quiz应用点击答题按钮后无法切换下一题如何解决
Flutter 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
相关产品推荐
相关产品推荐

