Quiz: Right or Wrong
Part of the Projects section of Coddy's Flutter journey. Lesson 11 of 36.
Tap an answer and the quiz should tell you at once: green if you were right, red if you were wrong, and the right answer in green either way, so you learn it.
The state needs to remember which answer you tapped. int? _picked is null until you tap one, so _picked != null means you have answered. Once you have, the buttons stop listening: the first line of _pick is a guard.
void _pick(int answer) {
if (_answered) return;
setState(() {
_picked = answer;
});
}A small function works out each button's color. null means "no color of my own", and the button keeps its theme color:
Color? _colorFor(int answer) {
if (!_answered) return null;
if (answer == _question.correct) return Colors.green;
if (answer == _picked) return Colors.red;
return null;
}The buttons now need their position, not only their text, so the loop counts: for (int i = 0; i < question.answers.length; i++) runs with i as 0, 1, 2 and 3.
Challenge
HardColor the answers:
- add
int? _picked, the getters_questionand_answered, and the_pickand_colorFormethods from the theory - loop over the answers by position with
for (int i = 0; ...) - each button calls
_pick(i); itsbackgroundColoris_colorFor(i), and its text is white when it has a color
Try it yourself
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
home: const QuizScreen(),
);
}
}
class Question {
const Question(this.text, this.answers, this.correct);
final String text;
final List<String> answers;
final int correct;
}
const List<Question> questions = [
Question('Which widget stacks its children from top to bottom?', ['Row', 'Column', 'Stack', 'Wrap'], 1),
Question('Which language do you write Flutter apps in?', ['Kotlin', 'Swift', 'Dart', 'JavaScript'], 2),
Question('What does setState do?', ['Rebuilds the widget', 'Saves the app', 'Closes the screen', 'Plays a sound'], 0),
Question('Which widget shows a list you can scroll?', ['Container', 'SizedBox', 'Padding', 'ListView'], 3),
Question('Which widget adds space around its child?', ['Padding', 'Center', 'Icon', 'Text'], 0),
];
class QuizScreen extends StatefulWidget {
const QuizScreen({super.key});
@override
State<QuizScreen> createState() => _QuizScreenState();
}
class _QuizScreenState extends State<QuizScreen> {
int _index = 0;
@override
Widget build(BuildContext context) {
final question = questions[_index];
final textTheme = Theme.of(context).textTheme;
return Scaffold(
appBar: AppBar(title: const Text('Flutter Quiz')),
body: Padding(
padding: const EdgeInsets.all(24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(question.text, style: textTheme.headlineSmall),
const SizedBox(height: 24),
for (String answer in question.answers)
Padding(
padding: const EdgeInsets.only(bottom: 12),
child: FilledButton.tonal(
style: FilledButton.styleFrom(
padding: const EdgeInsets.all(16),
),
onPressed: () {},
child: Text(answer),
),
),
],
),
),
);
}
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Projects
Practice on your own: Online Flutter compiler