I am studying by Dr. Angela Yu Flutter course on Udemy, currently making a Quizz app. Decided to challenge myself and make a separate class for buttons. Everything seems to work correctly, but when testing, erros occurs.
My code, main.dart:
import 'package:flutter/material.dart';
import 'package:quizler/quiz_brain.dart';
import 'package:rflutter_alert/rflutter_alert.dart';
void main() => runApp(const Quizzler());
class Quizzler extends StatelessWidget {
const Quizzler({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
backgroundColor: Colors.grey.shade900,
body: const SafeArea(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 10.0),
child: QuizPage(),
),
),
),
);
}
}
class QuestionButton extends StatefulWidget {
@override
State<QuestionButton> createState() => _questionButtonState();
final String label;
final MaterialColor colour;
final void func;
const QuestionButton(
{required this.label, required this.colour, required this.func});
}
class _questionButtonState extends State<QuestionButton> {
@override
Widget build(BuildContext context) {
return Expanded(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: TextButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(widget.colour)),
child: Text(
widget.label,
style: TextStyle(
fontSize: 20.0,
color: Colors.white,
),
),
onPressed: () {
setState() {
widget.func;
}
;
},
),
),
);
}
}
class QuizPage extends StatefulWidget {
const QuizPage({super.key});
@override
_QuizPageState createState() => _QuizPageState();
}
class _QuizPageState extends State<QuizPage> {
List<Widget> scoreKeeper = [];
bool isLast() {
if (scoreKeeper.length == 13) {
return true;
} else {
return false;
}
}
int score = 0;
String result(n) {
if (n == 0) {
return "are ya dumb??";
} else if (0 < n && n < 4) {
return "go to school";
} else {
return "testtest";
}
}
void checkAnswer(bool userPickedAnswer) {
bool correctAnswer = QuizBrain().getQuestionAnswer();
if (userPickedAnswer == correctAnswer) {
scoreKeeper.add(Icon(
Icons.check,
color: Colors.green,
));
score ;
} else {
scoreKeeper.add(Icon(
Icons.close,
color: Colors.red,
));
}
setState(() {
QuizBrain().nextQuestion();
});
if (isLast()) {
Alert(
context: context,
title: "END!",
desc: "You've finished this quiz! Ur score is - $score")
.show();
Alert(context: context, title: "END!", desc: result(score)).show();
scoreKeeper = [];
QuizBrain().startOver();
score = 0;
}
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
flex: 5,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Center(
child: Text(
QuizBrain().getQuestionText(),
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 25.0,
color: Colors.white,
),
),
),
),
),
QuestionButton(
label: 'True', colour: Colors.green, func: checkAnswer(true)),
QuestionButton(
label: 'False', colour: Colors.red, func: checkAnswer(false)),
Row(
children: scoreKeeper,
)
],
);
}
}
quiz_brain.dart:
int _questionNumber = 0;
bool finished = false;
class QuizBrain {
List<Question> _questionBank = [
Question('Some cats are actually allergic to humans', true),
Question('You can lead a cow down stairs but not up stairs.', false),
Question('Approximately one quarter of human bones are in the feet.', true),
Question('A slug\'s blood is green.', true),
Question('Buzz Aldrin\'s mother\'s maiden name was \"Moon\".', true),
Question('It is illegal to pee in the Ocean in Portugal.', true),
Question(
'No piece of square dry paper can be folded in half more than 7 times.',
false),
Question(
'In London, UK, if you happen to die in the House of Parliament, you are technically entitled to a state funeral, because the building is considered too sacred a place.',
true),
Question(
'The loudest sound produced by any animal is 188 decibels. That animal is the African Elephant.',
false),
Question(
'The total surface area of two human lungs is approximately 70 square metres.',
true),
Question('Google was originally called \"Backrub\".', true),
Question(
'Chocolate affects a dog\'s heart and nervous system; a few ounces are enough to kill a small dog.',
true),
Question(
'In West Virginia, USA, if you accidentally hit an animal with your car, you are free to take it home to eat.',
true),
];
void nextQuestion() {
if (_questionNumber < _questionBank.length - 1) {
_questionNumber ;
} else {
finished = true;
}
}
String getQuestionText() {
return _questionBank[_questionNumber].questionText;
}
bool getQuestionAnswer() {
return _questionBank[_questionNumber].questionAnswer;
}
bool isLast() {
if (_questionNumber == _questionBank.length) {
return true;
} else {
return false;
}
}
void startOver() {
_questionNumber = 0;
}
}
question.dart:
class Question {
late String questionText;
late bool questionAnswer;
Question(String q, bool a) {
questionText = q;
questionAnswer = a;
}
}
Didn't find any information abouts this on web.
CodePudding user response:
In the QuestionButton class, the func parameter is defined as a VoidCallback type, which means it should be a function that takes no arguments and returns void.
In the onPressed property of the button element, the widget.func is used, which means that it will call the func function passed as a parameter when constructing the QuestionButton widget.
When you are creating the QuestionButton widget in your code, you can pass the callback function like you have shown in your example. The checkAnswer(false) function will be called when the button is pressed.
class QuestionButton extends StatefulWidget {
@override
State<QuestionButton> createState() => _questionButtonState();
final String label;
final MaterialColor colour;
final VoidCallback? func;
const QuestionButton(
{required this.label, required this.colour, required this.func});
}
OnPress of button should be like this
onPressed: widget.func;
On Widget call you have to write callback like
QuestionButton(
label: 'False', colour: Colors.red, func : () {
checkAnswer(false); }),