Menu
CoddyTech

Quiz : Question suivante

Fait partie de la section Projets du Journey Flutter de Coddy. Leçon 12 sur 36.

Une question ne suffit pas pour faire un quiz. Après ta réponse, un bouton Suivant doit te mener à la question suivante, et une ligne en haut doit indiquer où tu en es.

Passer à la suite implique deux changements dans un seul setState : l’index augmente et la réponse est oubliée, afin que la nouvelle question s’affiche sans couleur :

void _next() {
  setState(() {
    _index++;
    _picked = null;
  });
}

Le bouton n’a de sens qu’une fois que tu as répondu, et pas à la dernière question, puisqu’il n’y en a pas de suivante (l’écran des résultats viendra plus tard). Une instruction if dans une collection l’ajoute uniquement dans ce cas : if (_answered && !_isLast) FilledButton(...).

On compte à partir de 1, les listes à partir de 0. L’étiquette affiche _index + 1 : 'Question ${_index + 1} of ${questions.length}'. La forme ${...} permet d’insérer une expression entière dans une chaîne, et pas seulement un nom.

challenge icon

Défi

Moyen

Passez d’une question à l’autre :

  • ajoutez un accesseur _isLast qui vaut true pour la dernière question, ainsi que la méthode _next présentée dans la théorie
  • au-dessus de la question, affichez Question 1 of 5 (avec les nombres réels) dans le style labelLarge du thème, puis laissez un espace de 24 pixels
  • sous les réponses, une fois que vous avez répondu et que la question n’est pas la dernière, affichez un FilledButton intitulé Next qui appelle _next

Essayez vous-même

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;
  int? _picked;

  Question get _question => questions[_index];
  bool get _answered => _picked != null;

  void _pick(int answer) {
    if (_answered) return;
    setState(() {
      _picked = answer;
    });
  }

  Color? _colorFor(int answer) {
    if (!_answered) return null;
    if (answer == _question.correct) return Colors.green;
    if (answer == _picked) return Colors.red;
    return null;
  }

  @override
  Widget build(BuildContext context) {
    final question = _question;
    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 (int i = 0; i < question.answers.length; i++)
              Padding(
                padding: const EdgeInsets.only(bottom: 12),
                child: FilledButton.tonal(
                  style: FilledButton.styleFrom(
                    backgroundColor: _colorFor(i),
                    foregroundColor: _colorFor(i) == null ? null : Colors.white,
                    padding: const EdgeInsets.all(16),
                  ),
                  onPressed: () => _pick(i),
                  child: Text(question.answers[i]),
                ),
              ),
          ],
        ),
      ),
    );
  }
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Projets

Entraînez-vous par vous-même : Compilateur Flutter en ligne