How to reset my quiz app questions choices

Viewed 44

I am new to flutter, I have built a quizz app that takes 5 questions randomly from a pool of questions and presents them to the user one after the other, then displays the total score at the end (on a different) screen with the option of retaking the quiz (with another set of randomly picked questions).

My issue I am facing is that when I choose to retake the quiz, if in the pool of questions presented there is a question from the past quiz, it still has its options highlighted (marked either wrong or correct as per the previous selection).

Can someone help me on how to totally dismiss previous choices after taking a quiz ?

This is an example of question answered in the previous quiz, and it came back with the option already highlighted (my previous answer).

[enter image description here][1]


  [1]: https://i.stack.imgur.com/U1YFf.png[enter image description here][1]

Here is my code:

import 'package:flutter/material.dart';
import 'package:percent_indicator/percent_indicator.dart';
import 'package:schoolest_app/widgets/quizz/quizz_image_container.dart';

import '../../models/quizz.dart';
import '../../widgets/quizz/options_widget.dart';
import '../../widgets/quizz/quizz_border_container.dart';
import '../../widgets/quizz/result_page.dart';

class QuizzDisplayScreen extends StatefulWidget {
  const QuizzDisplayScreen({
    Key? key,
  }) : super(key: key);

  static const routeName = '/quizz-display';

  @override
  State<QuizzDisplayScreen> createState() => _QuizzDisplayScreenState();
}

class _QuizzDisplayScreenState extends State<QuizzDisplayScreen> {
enter code here
  late String quizzCategoryTitle;
  late List<Question> categoryQuestions;
  late List<Question> quizCategoryQuestions;
  var _loadedInitData = false;
  @override
  void didChangeDependencies() {
    if (!_loadedInitData) {
      final routeArgs =
          ModalRoute.of(context)!.settings.arguments as Map<String, String>;
      quizzCategoryTitle = (routeArgs['title']).toString();
      // final categoryId = routeArgs['id'];
      categoryQuestions = questions.where((question) {
        return question.categories.contains(quizzCategoryTitle);
      }).toList();
      quizCategoryQuestions =
          (categoryQuestions.toSet().toList()..shuffle()).take(5).toList();
      _loadedInitData = true;
    }
    super.didChangeDependencies();
  }


  late PageController _controller;
  int _questionNumber = 1;
  int _score = 0;
  int _totalQuestions = 0;
  bool _isLocked = false;

  void _resetQuiz() {
    for (var element in quizCategoryQuestions) {
      setState(()=> element.isLocked == false);
    }
  }

  @override
  void initState() {
    super.initState();
    _controller = PageController(initialPage: 0);
  }

  @override
  void dispose() {
    _controller.dispose();

    _resetQuiz();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final myPrimaryColor = Theme.of(context).colorScheme.primary;
    final mySecondaryColor = Theme.of(context).colorScheme.secondary;
    double answeredPercentage =
        (_questionNumber / quizCategoryQuestions.length);

    return quizCategoryQuestions.isEmpty
        ? Scaffold(
            appBar: AppBar(
              title: Text(
                'Quizz - $quizzCategoryTitle',
                style: TextStyle(color: myPrimaryColor),
              ),
              iconTheme: IconThemeData(
                color: myPrimaryColor,
              ),
              centerTitle: true,
              backgroundColor: Colors.transparent,
              elevation: 0,
              flexibleSpace: Container(
                decoration: BoxDecoration(`enter code here`
                  borderRadius: const BorderRadius.only(`enter code here`
                    bottomLeft: Radius.circular(15),
                    bottomRight: Radius.circular(15),
                  ),
                  color: mySecondaryColor,
                  border: Border.all(color: myPrimaryColor, width: 1.0),
                ),
              ),
            ),
            body: const Center(
              child: Text('Cette catégorie est vide pour l\'instant'),
            ))
        : Scaffold(
            appBar: AppBar(
              title: Text(
                'Quizz - $quizzCategoryTitle',
                style: TextStyle(color: myPrimaryColor),
              ),
              iconTheme: IconThemeData(
                color: myPrimaryColor,
              ),
              centerTitle: true,
              backgroundColor: Colors.transparent,
              elevation: 0,
              flexibleSpace: Container(
                decoration: BoxDecoration(
                  borderRadius: const BorderRadius.only(
                    bottomLeft: Radius.circular(15),
                    bottomRight: Radius.circular(15),
                  ),
                  color: mySecondaryColor,
                  border: Border.all(color: myPrimaryColor, width: 1.0),
                ),
              ),
            ),
            body: Container(
              // height: 600,
              width: double.infinity,
              padding: const EdgeInsets.symmetric(horizontal: 16.0),
              child: Column(
                children: [
                  const SizedBox(height: 10),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceAround,
                    children: [
                      Text(
                        'Question $_questionNumber/${quizCategoryQuestions.length}',
                        style: const TextStyle(
                            fontSize: 20, fontWeight: FontWeight.bold),
                      ),
                      CircularPercentIndicator(
                        radius: 40,
                        // animation: true,
                        // animationDuration: 2000,
                        percent: answeredPercentage,
                        progressColor: myPrimaryColor,
                        backgroundColor: Colors.cyan.shade100,
                        circularStrokeCap: CircularStrokeCap.round,
                        center: Text(
                          // ignore: unnecessary_brace_in_string_interps
                          '${(answeredPercentage * 100).round()} %',
                          style: const TextStyle(
                              fontSize: 10, fontWeight: FontWeight.bold),
                        ),

                        // lineWidth: 10,
                      )
                    ],
                  ),
                  const SizedBox(height: 10),
                  Divider(
                    thickness: 1,
                    color: myPrimaryColor,
                  ),
                  Expanded(
                    child: PageView.builder(
                      itemCount: quizCategoryQuestions.length,
                      controller: _controller,
                      physics: const NeverScrollableScrollPhysics(),
                      itemBuilder: (context, index) {
                        final _question = quizCategoryQuestions[index];
                        return buildQuestion(_question);
                      },
                    ),
                  ),
                  _isLocked
                      ? buildElevatedButton(context)
                      : const SizedBox.shrink(),
                  const SizedBox(height: 10),
                ],
              ),
            ),
          );
  }

  Column buildQuestion(Question question) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const SizedBox(height: 10),
        question.text!.isNotEmpty
            ? QuizzBorderContainer(
                childWidget: Text(
                  question.text!,
                  style: const TextStyle(
                      fontSize: 20, fontWeight: FontWeight.bold),
                ),
              )
            : const SizedBox.shrink(),
        question.imagePath!.isNotEmpty
            ? QuizzImageContainer(imagePath: question.imagePath!)
            : const SizedBox.shrink(),
        Expanded(
          child: OptionsWidget(
            question: question,
            onClickedOption: (option) {
              if (question.isLocked) {
                return;
              } else {
                setState(() {
                  question.isLocked = true;
                  question.selectedOption = option;
                });
                _isLocked = question.isLocked;
                if (question.selectedOption!.isCorrect) {
                  _score++;
                }
              }
            },
          ),
        ),
      ],
    );
  }

  ElevatedButton buildElevatedButton(BuildContext context) {
    final mySecondaryColor = Theme.of(context).colorScheme.secondary;
    return ElevatedButton(
      onPressed: () {
        if (_questionNumber < quizCategoryQuestions.length) {
          _controller.nextPage(
            duration: const Duration(milliseconds: 1000),
            curve: Curves.easeInExpo,
          );
          setState(() {
            _questionNumber++;
            _isLocked = false;
          });
        } else {
          setState(() {
            // _isLocked = false;
            _totalQuestions = quizCategoryQuestions.length;
          });
          Navigator.pushReplacement(
            context,
            MaterialPageRoute(
              builder: (context) =>
                  ResultPage(score: _score, totalQuestions: _totalQuestions),
            ),
          );
        }
      },
      child: Text(
        _questionNumber < quizCategoryQuestions.length
            ? 'Suivant'
            : 'Voir le résultat',
        style: TextStyle(
          color: mySecondaryColor,
          fontWeight: FontWeight.bold,
        ),
      ),
    );
  }
}

I don't seem to the solution to this.

And this is the code on the result page:

import 'package:flutter/material.dart';

import '../../screens/quizz/quizz_screen.dart';

class ResultPage extends StatefulWidget {
  final int score;
  final int totalQuestions;

  const ResultPage({
    Key? key,
    required this.score,
    required this.totalQuestions,
  }) : super(key: key);

  @override
  State<ResultPage> createState() => _ResultPageState();
}

class _ResultPageState extends State<ResultPage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: SizedBox(
          height: 150,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              Text(
                'You got ${widget.score}/${widget.totalQuestions}',
                style: const TextStyle(
                  fontSize: 30,
                  fontWeight: FontWeight.bold,
                ),
              ),


              ElevatedButton(
                onPressed: () {
                  Navigator.pop(context);
                  Navigator.pushReplacement(
                    context,
                    MaterialPageRoute(
                      builder: (context) => const QuizzScreen(),
                    ),
                  );
                },
                child: const Text('OK'),
              ),
            ],
          ),
        ),
      ),
    );
  }

}

I don't know what is missing to get the reset right.

1 Answers

When you want to take retest try to dispose all the answers which are saved in the memory. Or you can use these navigators to which might help you in solving the issue. Try using pushReplacement or pushAndRemoveUntil when navigating to retest, this will clear the memory of last pages and you will achive the goal which you want.

Related