Menu
CoddyTech

Quiz : Tenir le score

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

Un quiz est plus amusant quand tu peux voir où tu en es. Garde un score dans l’état, ajoute un point pour chaque bonne réponse et affiche-le dans la barre supérieure.

Le meilleur endroit pour compter est _pick, à l’intérieur du même setState qui stocke la réponse. Compare la réponse que tu as donnée, answer, à la bonne réponse :

setState(() {
  _picked = answer;
  if (answer == _question.correct) {
    _score++;
  }
});

La vérification au début de _pick empêche déjà un deuxième appui : chaque question peut donc rapporter au maximum un point.

Un AppBar accepte actions:, une liste de widgets placés à son extrémité droite. Mets-y le score, enveloppé dans un Center pour qu’il soit centré en hauteur dans la barre, avec 16 pixels de marge intérieure à droite.

challenge icon

Défi

Moyen

Tenir le score :

  • ajouter int _score = 0; à l’état
  • dans _pick, lui ajouter un lorsque la réponse est correcte
  • afficher Score: 0 (avec le score réel) dans les actions de la barre supérieure, avec le style titleMedium du thème, centré, et une marge intérieure de 16 pixels à droite

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;
  bool get _isLast => _index == questions.length - 1;

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

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

  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 ${_index + 1} of ${questions.length}',
              style: textTheme.labelLarge,
            ),
            const SizedBox(height: 24),
            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]),
                ),
              ),
            if (_answered && !_isLast)
              FilledButton(
                onPressed: _next,
                child: const Text('Next'),
              ),
          ],
        ),
      ),
    );
  }
}
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