Get all the scores from all widgets

Issue

I am building a quiz app and I created a custom widget to save me a lot of time as I have a lot of questions for the quiz. Everything works apart from the scoring system. If I create multiple instances of the same widget the score will not be incremented and it will stay on 1. Is there any way I can pass each score of the widgets to a global variable in my main widget so then I can add all the scores? (I’m new to flutter).

Custom Widget

class Questions extends StatefulWidget {
  final String imagePath;
  final String question;
  final String answer1;
  final String answer2;
  final String answer3;
  final String answer4;
  final bool iscorrectAnswer1;
  final bool iscorrectAnswer2;
  final bool iscorrectAnswer3;
  final bool iscorrectAnswer4;

  int score = 0;

  bool questionsAnswered = false;

  Questions(
    this.imagePath,
    this.question,
    this.answer1,
    this.answer2,
    this.answer3,
    this.answer4,
    this.iscorrectAnswer1,
    this.iscorrectAnswer2,
    this.iscorrectAnswer3,
    this.iscorrectAnswer4,
  );

  @override
  _QuestionsState createState() => _QuestionsState();
}

class _QuestionsState extends State<Questions> {
  disableButton() {
    setState(() {
      widget.questionsAnswered = true;
      Quiz().score += widget.score;
    });
  }

  @override
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        SizedBox(
          width: 600,
          height: 600,
          child: Image.asset(widget.imagePath),
        ),
        Align(
            alignment: Alignment.topCenter,
            child: Padding(
              padding: EdgeInsets.only(
                top: 20,
              ),
              child: Text(
                widget.question,
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 38,
                ),
              ),
            )),
        Padding(
            padding: EdgeInsets.only(
              top: 40,
            ),
            child: SizedBox(
              width: 500,
              height: 60,
              child: ClipRRect(
                borderRadius: BorderRadius.all(Radius.circular(15)),
                child: ElevatedButton(
                    style: ButtonStyle(
                      backgroundColor: MaterialStateProperty.all(
                        Color(0xFF304e60),
                      ),
                    ),
                    child: Text(
                      widget.answer1,
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 15,
                      ),
                    ),
                    onPressed: widget.questionsAnswered == false
                        ? () {
                            setState(() {
                              if (widget.iscorrectAnswer1 == true) {
                                ScaffoldMessenger.of(context).showSnackBar(
                                  SnackBar(
                                    content: Text('Correct!'),
                                  ),
                                );
                                disableButton();
                                widget.score += 1;
                              } else {
                                ScaffoldMessenger.of(context)
                                    .showSnackBar(SnackBar(
                                  content: Text('Wrong Answer!'),
                                ));
                              }
                            });
                            print(widget.iscorrectAnswer1);
                            print(widget.score);
                          }
                        : null),
              ),
            )),
        Padding(
            padding: EdgeInsets.only(
              top: 10,
            ),
            child: SizedBox(
              width: 500,
              height: 60,
              child: ClipRRect(
                borderRadius: BorderRadius.all(Radius.circular(15)),
                child: ElevatedButton(
                    style: ButtonStyle(
                        backgroundColor:
                            MaterialStateProperty.all(Color(0xFF565462))),
                    child: Text(
                      widget.answer2,
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 15,
                      ),
                    ),
                    onPressed: widget.questionsAnswered == false
                        ? () {
                            setState(() {
                              if (widget.iscorrectAnswer2 == true) {
                                ScaffoldMessenger.of(context).showSnackBar(
                                  SnackBar(
                                    content: Text('Correct!'),
                                  ),
                                );
                                widget.score += 1;
                              } else {
                                disableButton();
                                ScaffoldMessenger.of(context)
                                    .showSnackBar(SnackBar(
                                  content: Text('Wrong Answer!'),
                                ));
                              }
                            });
                          }
                        : null),
              ),
            )),
        Padding(
          padding: EdgeInsets.only(
            top: 10,
          ),
          child: SizedBox(
            width: 500,
            height: 60,
            child: ClipRRect(
              borderRadius: BorderRadius.all(Radius.circular(15)),
              child: ElevatedButton(
                  style: ButtonStyle(
                      backgroundColor:
                          MaterialStateProperty.all(Color(0xFF84693b))),
                  child: Text(
                    widget.answer3,
                    style: TextStyle(
                      color: Colors.white,
                      fontSize: 15,
                    ),
                  ),
                  onPressed: widget.questionsAnswered == false
                      ? () {
                          setState(() {
                            if (widget.iscorrectAnswer3 == true) {
                              ScaffoldMessenger.of(context).showSnackBar(
                                SnackBar(
                                  content: Text('Correct!'),
                                ),
                              );

                              widget.score += 1;
                            } else {
                              disableButton();
                              ScaffoldMessenger.of(context)
                                  .showSnackBar(SnackBar(
                                content: Text('Wrong Answer!'),
                              ));
                            }
                          });
                        }
                      : null),
            ),
          ),
        )
      ],
    );
  }
}

Main widget where I call this custom widget

class Quiz extends StatefulWidget {
  Quiz({Key? key}) : super(key: key);

  int score = 0;

  @override
  _QuizState createState() => _QuizState();
}

class _QuizState extends State<Quiz> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('CyberQuiz'),
        ),
        body: SingleChildScrollView(
            scrollDirection: Axis.vertical,
            child: Column(
              children: [
                Questions(
                  'images/malware_quiz.jpeg',
                  '1. What is a malware?',
                  'Designed to damage computers, servers or any other devices',
                  "Used to get user's credentials",
                  "It's used to destroy networks",
                  '',
                  true,
                  false,
                  false,
                  false,
                ),
              ],
            )));
  }
}

Solution

As you suggest in your question, you could create a global variable and increment/decrease/reset that.

Basic example code:


import 'package:flutter/material.dart';

class Score {
  static int score = 0;
}

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

  @override
  State<ScoreCounter> createState() => _ScoreCounterState();
}

class _ScoreCounterState extends State<ScoreCounter> {
  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        Expanded(
          child: ElevatedButton(
            onPressed: () {
              setState(() {
                Score.score++;
              });
            },
            child: Text('increase score'),
          ),
        ),
        Expanded(child: Text(Score.score.toString()))
      ],
    );
  }
}

Another option is to use the Provider package – link here which has an example

Provider Package

Answered By – Kdon

Answer Checked By – Cary Denson (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *