Flutter Quiz App with REST API
Introduction
In this section, you will learn to build a simple quiz app in Flutter using API.
Setup
Ensure your pubspec.yaml
includes dependencies for Flutter and the http
package for API requests:
dependencies:
flutter:
sdk: flutter
http: ^1.2.1
Main Screen
The main screen displays a play button that navigates to the quiz player screen.
import 'package:flutter/material.dart';
void main() => runApp(const QuizApp());
class QuizApp extends StatelessWidget {
const QuizApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: MainScreen(),
);
}
}
class MainScreen extends StatelessWidget {
const MainScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Trivia Quiz')),
body: Center(
child: ElevatedButton(
child: const Text('Play'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const PlayerScreen()),
);
},
),
),
);
}
}
Player Screen
The player screen fetches and displays a question, presenting multiple choice answers.
class PlayerScreen extends StatefulWidget {
const PlayerScreen({super.key});
@override
_PlayerScreenState createState() => _PlayerScreenState();
}
class _PlayerScreenState extends State<PlayerScreen> {
int currentQuestionIndex = 0;
int score = 0;
List<Question> questions = [];
Future<void> fetchQuestions() async {
final response = await http.get(Uri.parse('https://opentdb.com/api.php?amount=2&category=18&difficulty=easy&type=multiple'));
if (response.statusCode == 200) {
final data = json.decode(response.body);
setState(() {
questions = List<Question>.from(data['results'].map((question) => Question.fromJson(question)));
});
} else {
throw Exception('Failed to load questions');
}
}
@override
void initState() {
super.initState();
fetchQuestions();
}
void checkAnswer(String selectedAnswer) {
if (questions[currentQuestionIndex].correctAnswer == selectedAnswer) {
score++;
}
if (currentQuestionIndex < questions.length - 1) {
setState(() {
currentQuestionIndex++;
});
} else {
Navigator.push(context, MaterialPageRoute(builder: (context) => ScoreScreen(score: score)));
}
}
@override
Widget build(BuildContext context) {
if (questions.isEmpty) {
return Scaffold(
appBar: AppBar(title: const Text('Question')),
body: const Center(child: CircularProgressIndicator()),
);
}
final question = questions[currentQuestionIndex];
return Scaffold(
appBar: AppBar(title: const Text('Question')),
body: ListView(
children: <Widget>[
ListTile(title: Text(question.question)),
...question.answers.map((answer) => ListTile(
title: Text(answer),
onTap: () => checkAnswer(answer),
)).toList(),
],
),
);
}
}
Question Model
Create a model to represent a question and its answers.
class Question {
final String question;
final List<String> answers;
final String correctAnswer;
Question({required this.question, required this.answers, required this.correctAnswer});
factory Question.fromJson(Map<String, dynamic> json) {
var incorrectAnswers = List<String>.from(json['incorrect_answers']);
var correctAnswer = json['correct_answer'];
incorrectAnswers.add(correctAnswer);
incorrectAnswers.shuffle();
return Question(
question: json['question'],
answers: incorrectAnswers,
correctAnswer: correctAnswer,
);
}
}
Score Screen
After answering questions, navigate to the results screen to display the score.
import 'package:flutter/material.dart';
class ScoreScreen extends StatelessWidget {
final int score;
ScoreScreen({super.key, required this.score});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Score')),
body: Center(
child: Text('Your score is: $score', style: const TextStyle(fontSize: 24)),
),
);
}
}