Flutter中ListView Builder点击选项后切换下一题的实现
Solution
First, fix the typo in your API request code: change Qustion to Question in the late Future<List<Qustion>> questions; line—this will prevent a compile error.
Next, add state variables to track your progress through the questions:
// Add these inside your State class int _currentQuestionIndex = 0; List<Question>? _questions; int _score = 0; // Optional: track correct answers
Then, update your FutureBuilder to use these state variables and render a single question at a time (no need for ListView.builder here):
body: FutureBuilder( future: questions, builder: (context, AsyncSnapshot snapshot) { if (snapshot.hasError) { return Text('${snapshot.error}'); } else if (snapshot.hasData) { _questions = snapshot.data as List<Question>; // Check if all questions are completed if (_currentQuestionIndex >= _questions!.length) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('Quiz Completed!'), Text('Your Score: $_score/${_questions!.length}'), // Show score if tracking ], ), ); } final currentQuestion = _questions![_currentQuestionIndex]; return renderBody( currentQuestion.imagePath, currentQuestion.question, currentQuestion.value, onAnswer: (userAnswer) { // Optional: check if answer is correct if (userAnswer == currentQuestion.value) { setState(() { _score++; }); } // Move to next question setState(() { _currentQuestionIndex++; }); }, ); } return Center(child: Text('Loading')); }, ),
Modify the renderBody function to accept an answer callback:
// Update the function signature to include the callback Widget renderBody(String image, String question, bool value, {required Function(bool) onAnswer}) { return Padding( padding: EdgeInsets.symmetric(horizontal: 10.0), child: Container( width: MediaQuery.of(context).size.width * .90, child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.stretch, children: <Widget>[ // ... (your existing image and question code remains the same) Row( children: <Widget>[ Expanded( child: Container( height: 200, padding: EdgeInsets.all(5.0), child: ElevatedButton.icon( style: ElevatedButton.styleFrom( primary: Colors.greenAccent[400], shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10.0), ), ), onPressed: () { onAnswer(true); // Pass user's True answer }, icon: Icon(Icons.check_sharp), label: Text('True')), ), ), Expanded( child: Container( height: 200, padding: EdgeInsets.all(5.0), child: ElevatedButton.icon( style: ElevatedButton.styleFrom( primary: Colors.red, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10.0), ), ), onPressed: () { onAnswer(false); // Pass user's False answer }, icon: Icon(Icons.clear), label: Text('False')), ), ), ], ), ], ), ), ); }
Key Changes Explained:
- State Variables:
_currentQuestionIndextracks which question the user is on,_questionsstores the loaded list once the API call finishes, and_score(optional) keeps track of correct answers. - FutureBuilder Adjustment: Instead of a ListView, we directly render the current question using the index. When the index exceeds the number of questions, we show a completion screen.
- Answer Callback: The
onAnswerfunction is passed torenderBody, so when the user taps True/False, we trigger a state update to move to the next question (and optionally update the score).
内容的提问来源于stack exchange,提问作者Quinton
相关产品推荐
相关产品推荐

