It shows this error although I have added late and required in the Question class constructor. It's repeatedly shows
Exception caught by widgets library
The following LateError was thrown building _BodyBuilder:
LateInitializationError: Field 'ques' has not been initialized
Main class:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'QuestionsAnswers.dart';
void main() {
runApp(const Quizzler());
}
class Quizzler extends StatelessWidget {
const Quizzler({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: SafeArea(
child: Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
backgroundColor: Colors.grey[900],
leading: Icon(Icons.games),
title: Text(
'Quizzler',
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
fontStyle: FontStyle.italic,
color: Colors.white,
),
),
),
body: QuizPlay(),
),
),
);
}
}
class QuizPlay extends StatefulWidget {
const QuizPlay({Key? key}) : super(key: key);
#override
State<QuizPlay> createState() => _QuizplayState();
}
class _QuizplayState extends State<QuizPlay> {
List<Icon> score=[];// array of score icon
List<Questions>questionsAndAnswers=[
Questions(a:'Pakistan is an under developed country',b:true),
Questions(a:'Imran Khan is the Prime Minister of Pakistan',b:true),
Questions(a:'Y comes after U',b:false)
];
int questiontracker=0;// variable to increment of questions
#override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
flex: 4,
child: Padding(
padding: EdgeInsets.all(10.0),
child: Center(
child: Text(
questionsAndAnswers[questiontracker].ques,
style: TextStyle(
fontSize: 25.0,
color: Colors.white70,
),
),
),
),
),
Expanded(
child: Padding(
padding: EdgeInsets.all(10.0),
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.green),
),
onPressed: () {
//Yes button
bool answer=questionsAndAnswers[questiontracker].ans;
if (answer==true)
{
print('correct answer');
}
else
{
print('wrong answer ');
}
setState(() {
questiontracker++;
score.add(Icon(Icons.check,color: Colors.green,)) ;
});
},
child: Text(
'Yes',
style: TextStyle(
fontSize: 20.0,
),
),
),
),
),
Expanded(
child: Padding(
padding: EdgeInsets.all(10.0),
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.red),
),
onPressed: () {
// No button
bool answer=questionsAndAnswers[questiontracker].ans;
if (answer==false)
{
print('correct answer');
}
else
{
print('wrong answer ');
}
setState(() {
questiontracker++;
score.add(Icon(Icons.close,color: Colors.red,)) ;
});
},
child: Text(
'No',
style: TextStyle(
fontSize: 20.0,
),
),
),
),
),
Row(
children: score,
),
],
);
}
}
###Question CLASS###
class Questions{
late String ques;
late bool ans;
Questions({required String a,required bool b})
{
a=ques;
b=ans;
}
}
make it
ques = a;
ans = b;
This stores the value on the right in the value on the left.
Your class constructor Questions is wrong, change it to:
class Questions{
late String ques;
late bool ans;
Questions({required String a,required bool b}) {
ques = a;
and = b;
}
}
What is the purpose of having your questions as a plain class? I'd suggest turning it into a module class which in turn should be
class Question
{
String? ques;
bool? ans;
Question({
this.ques, this.ans});
}
and when you want to initialize a question I'd suggest creating a list
List<Question> questions = [];
question.add(Question("question",true));
// add more as you wish
This will allow you to turn it into JSON which will enable you to maybe provide questions from an online database to the app without needing to update the app every time you want to add a question.
Related
Here is the code for a Quiz App I have been making. This is the main.dart file.
import 'package:flutter/material.dart';
import 'list.dart';
void main() {
runApp(
const Quizzler(),
);
}
class Quizzler extends StatefulWidget {
const Quizzler({Key? key}) : super(key: key);
#override
State<Quizzler> createState() => _QuizzlerState();
}
class _QuizzlerState extends State<Quizzler> {
List<Widget> scoreKeeper = [];
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.black,
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
flex: 6,
child: Padding(
padding: const EdgeInsets.all(32.0),
child: Center(
child: Text(
Quiz().getQuestion(),
style: const TextStyle(
color: Colors.white,
fontSize: 20,
),
textAlign: TextAlign.center,
),
),
),
),
boolButton(Colors.green, 'True'),
boolButton(Colors.red, 'False'),
Row(
children: scoreKeeper,
),
],
),
),
);
}
Expanded boolButton(Color c, String s) {
return Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(c),
),
onPressed: () {
setState(
() {
switcher(s);
Quiz().nextQuestion();
},
);
},
child: Text(
s,
),
),
),
);
}
switcher(String s) {
if (Quiz().getAnswer().toLowerCase() == s.toLowerCase()) {
scoreKeeper.add(
const Icon(
Icons.check,
color: Colors.green,
),
);
} else {
scoreKeeper.add(
const Icon(
Icons.close,
color: Colors.red,
),
);
}
}
}
This is the list.dart file that I imported onto the main.dart file:
import 'question.dart';
class Quiz {
int _counter = 0;
final List<Question> _q = [
Question(
'Cows can only be lead up a flight of stairs and not down.',
'False',
),
Question(
'Approximately one quarter of human bones are in the feet.',
'True',
),
Question(
'A slug\'s blood is green.',
'True',
),
];
void nextQuestion() {
_counter++;
}
String getQuestion() {
return _q[_counter].question;
}
String getAnswer() {
return _q[_counter].answer;
}
}
And this is the question.dart file that I imported onto the list.dart file:
class Question {
String question;
String answer;
Question(this.question, this.answer);
}
In the Quiz app, once I hit True or False it just shows a tick for the right answer (False) and a cross for the wrong answer (True), without moving to the next question. How do I fix this?
Here, you call any variables or methods from Quiz class by calling directly by Quiz(), basically problems occur here.
By calling Quiz() every time you created a new object, there is no tracking of this object. Because you don't save the object.
So, at first, save the object like that...
Quiz quiz = Quiz();
then wherever you call by Quiz(), replace by quiz.
be like..... quiz.getQuestion(),quiz.nextQuestion(),quiz.getAnswer()
I add all three dart file added below ... with the solution of showing a ques ending alert snackbar.
This is the main.dart file.
import 'package:flutter/material.dart';
import 'list.dart';
void main() {
runApp(
const Quizzler(),
);
}
class Quizzler extends StatefulWidget {
const Quizzler({Key? key}) : super(key: key);
#override
State<Quizzler> createState() => _QuizzlerState();
}
class _QuizzlerState extends State<Quizzler> {
/// This is for show snack bar
final _messangerKey = GlobalKey<ScaffoldMessengerState>();
Quiz quiz = Quiz();
List<Widget> scoreKeeper = [];
#override
Widget build(BuildContext context) {
return MaterialApp(
scaffoldMessengerKey: _messangerKey,
home: Scaffold(
backgroundColor: Colors.black,
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
flex: 6,
child: Padding(
padding: const EdgeInsets.all(32.0),
child: Center(
child: Text(
quiz.getQuestion(),
style: const TextStyle(
color: Colors.white,
fontSize: 20,
),
textAlign: TextAlign.center,
),
),
),
),
boolButton(Colors.green, 'True'),
boolButton(Colors.red, 'False'),
Row(
children: scoreKeeper,
),
],
),
),
);
}
Expanded boolButton(Color c, String s) {
return Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(c),
),
onPressed: () {
(quiz.q.length - 1) > quiz.counter ? setState(
() {
switcher(s);
quiz.nextQuestion();
},
) : _messangerKey.currentState!.showSnackBar(
const SnackBar(duration: Duration(seconds : 2),content: Text('No more questions')));
},
child: Text(
s,
),
),
),
);
}
switcher(String s) {
if (quiz.getAnswer().toLowerCase() == s.toLowerCase()) {
scoreKeeper.add(
const Icon(
Icons.check,
color: Colors.green,
),
);
} else {
scoreKeeper.add(
const Icon(
Icons.close,
color: Colors.red,
),
);
}
}
}
This is the list.dart file
import 'question.dart';
class Quiz {
int counter = 0;
final List<Question> q = [
Question(
'Cows can only be lead up a flight of stairs and not down.',
'False',
),
Question(
'Approximately one quarter of human bones are in the feet.',
'True',
),
Question(
'A slug\'s blood is green.',
'True',
),
];
void nextQuestion() {
counter++;
}
String getQuestion() {
return q[counter].question;
}
String getAnswer() {
return q[counter].answer;
}
}
And this is the question.dart file
class Question {
String question;
String answer;
Question(this.question, this.answer);
}
I am trying to create a responsive chatbot with quick replies. I want to make a button on pressed function call to another class's function. I tried using the callback. But i think i am doing something wrong. Kindly help me.
typedef void mycallback(String label);
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
User? user = FirebaseAuth.instance.currentUser;
UserModel loggedInUser = UserModel();
late DialogFlowtter dialogFlowtter;
final TextEditingController messageController = TextEditingController();
#override
void initState() {
super.initState();
DialogFlowtter.fromFile().then((instance) => dialogFlowtter = instance);
}
#override
Widget build(BuildContext context) {
var themeValue = MediaQuery.of(context).platformBrightness;
Body(
hi: sendMessage,
);
return Scaffold(
backgroundColor: themeValue == Brightness.dark
? HexColor('#262626')
: HexColor('#FFFFFF'),
appBar: AppBar(
//app bar ui
),
actions: [
//list if widget in appbar actions
PopupMenuButton(
icon: Icon(Icons.menu),
color: Colors.blue,
itemBuilder: (context) => [
PopupMenuItem<int>(
value: 0,
child: Text(
"Log out",
style: TextStyle(color: Colors.white),
),
),
],
onSelected: (item) => {logout(context)},
),
],
),
body: SafeArea(
child: Column(
children: [
Expanded(child: Body(messages: messages)),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 5,
),
child: Row(
children: [
Expanded(
child: TextFormField(
controller: messageController,
style: TextStyle(
color: themeValue == Brightness.dark
? Colors.white
: Colors.black,
fontFamily: 'Poppins'),
decoration: new InputDecoration(
enabledBorder: new OutlineInputBorder(
borderSide: new BorderSide(
color: themeValue == Brightness.dark
? Colors.white
: Colors.black),
borderRadius: BorderRadius.circular(15)),
hintStyle: TextStyle(
color: themeValue == Brightness.dark
? Colors.white54
: Colors.black54,
fontSize: 15,
fontStyle: FontStyle.italic,
),
labelStyle: TextStyle(
color: themeValue == Brightness.dark
? Colors.white
: Colors.black),
hintText: "Type here...",
),
),
),
IconButton(
color: themeValue == Brightness.dark
? Colors.white
: Colors.black,
icon: Icon(Icons.send),
onPressed: () {
sendMessage(messageController.text);
messageController.clear();
},
),
],
),
),
],
),
),
);
}
void sendMessage(String text) async {
if (text.isEmpty) return;
setState(() {
//do main function
});
}
}
The class from where i want to call the function
class Body extends StatelessWidget {
final List<Map<String, dynamic>> messages;
final mycallback? hi;
const Body({
Key? key,
this.messages = const [],
this.buttons = const [],
this.hi,
this.onPressed,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return ListView.separated(
itemBuilder: (context, i) {
var obj = messages[messages.length - 1 - i];
Message message = obj['message'];
bool isUserMessage = obj['isUserMessage'] ?? false;
String label = obj['label'];
return Row(
mainAxisAlignment:
isUserMessage ? MainAxisAlignment.end : MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
_MessageContainer(
message: message,
isUserMessage: isUserMessage,
),
ElevatedButton(
child: Text(label),
onPressed: () => {hi ?? (label)},//This is where i want to call
style: ElevatedButton.styleFrom(
primary: Colors.blueAccent,
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
textStyle: TextStyle(fontWeight: FontWeight.bold)),
),
],
);
},
separatorBuilder: (_, i) => Container(height: 10),
itemCount: messages.length,
reverse: true,
padding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 20,
),
);
}
}
The code runs without errors but nothing happens when i press the buttons.
This is how I'd implement something like that. You're basically asking for a void as parameter inside your widget. Almost like a TextButton or another widget like that.
You can use this with two stateful widets as well, since you're borrowing the function from one to another.
Also I think this would be done better with provider so I suggest you look into it. (I don't have enough experience with it)
https://pub.dev/packages/provider
class MyHomePage extends StatefulWidget {
const MyHomePage({
Key? key,
}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int x = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('An app'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('$x'),
TestWidget(onTap: () {
setState(() {
x++;
});
})
],
),
),
);
}
}
class TestWidget extends StatelessWidget {
final VoidCallback onTap;
const TestWidget({Key? key, required this.onTap}) : super(key: key);
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: Container(
padding: const EdgeInsets.all(20),
color: Colors.blue,
child: Text('test')),
);
}
}
I found the error.
In the class HomeScreen, I missed this line.
child: Body(
messages: messages,
hi: (text) => {sendMessage(text)}, //this line
)
After adding this line, the callback worked fine!
I am still relatively new to coding and only still learning dart. I have made multiple of the same button using classes, how do i customize each button individually, please can you help. Here is the code:
Button Code:
class JeffButton extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.fromLTRB(0.0, 9.0, 0.0, 0.0),
child: TextButton.icon(
onPressed: () => {},
icon: Column(
children: [
Icon(
Icons.add,
color: Colors.white,
size: 85,
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Text(
'Label',
style: TextStyle(
color: Colors.white,
),
),
),
],
),
label: Text(
'', //'Label',
style: TextStyle(
color: Colors.white,
),
),
),
);
}
}
Other Code:
class home_buttons {
List<Widget> jeffButtons = [
JeffButton(),
JeffButton(),
JeffButton(),
JeffButton(),
JeffButton(),
JeffButton(),
];
}
You'll need to have properties on your class - That way, when you create instances of your button, you can pass different values as arguments to the constructor, and those different values can be used to customize each instance of the button.
So, for example, if you want to customize the title label, give your class a title property:
class JeffButton extends StatelessWidget {
final String title;
JeffButton({required this.title});
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.fromLTRB(0.0, 9.0, 0.0, 0.0),
child: TextButton.icon(
onPressed: () => {},
label: Text(
title, // Use the title property to set the label text,
style: TextStyle(
color: Colors.white,
),
),
),
);
}
}
Then you can set different titles for each button:
final continueButton = JeffButton(title: 'Continue');
final cancelButton = JeffButton(title: 'Cancel');
You can create constructors, here is an example for padding.
class JeffButton extends StatelessWidget {
EdgeInsetsGeometry padding;
JeffButton({this.padding = EdgeInsets.all(8)});
#override
Widget build(BuildContext context) {
return Padding(
padding: padding,
);
}
}
You can use it like:
JeffButton(padding: EdgeInsets.all(10));
I am facing this error it runs perfectly but it show no output and display the
following error
type '_CompactLinkedHashSet' is not a subtype of type 'List' in type cast
Flutter
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:quizler/Question.dart';
import 'Question.dart';
void main() => runApp(quizler());
class quizler extends StatelessWidget {
const quizler({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.grey.shade900,
body: SafeArea(
child: QuizzPage(),
),
),
);
}
}
class QuizzPage extends StatefulWidget {
const QuizzPage({Key? key}) : super(key: key);
#override
_QuizzPageState createState() => _QuizzPageState();
}
class _QuizzPageState extends State<QuizzPage> {
List<Widget> scoreKeeper = [];
List<Question> questionBank={
Question(q: 'Moon Color is gray',a:false),
Question(q: 'Independence Day of pakistan was 1947',a:true),
Question(q: 'Tesla was the owner of Starlink company',a:false),
} as List<Question> ;
int questionNumber = 0;
#override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
flex: 5,
child: Padding(
padding: EdgeInsets.all(15.0),
child: Center(
child: Text(
questionBank[questionNumber].questionText,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 25.0,
color: Colors.white,
),
),
),
),
),
Expanded(
child: Padding(
padding: EdgeInsets.all(20.0),
child: FlatButton(
textColor: Colors.white,
color: Colors.green,
onPressed: () {
bool correctAnswer = questionBank[questionNumber].questionAnswer;
if (correctAnswer == true) {
setState(() {
questionNumber++;
scoreKeeper.add(
Icon(Icons.check, color: Colors.green),
);
});
} else {
setState(() {
questionNumber++;
scoreKeeper.add(
Icon(
Icons.check,
color: Colors.red,
),
);
});
}
},
child: Text(
'True',
),
),
),
),
Expanded(
child: Padding(
padding: EdgeInsets.all(20.0),
child: FlatButton(
textColor: Colors.white,
color: Colors.red,
onPressed: () {
bool correctAnswer = questionBank[questionNumber].questionAnswer;
if (correctAnswer == false) {
setState(
() {
questionNumber++;
scoreKeeper.add(
Icon(Icons.check, color: Colors.green),
);
},);
}
else{
setState(
() {
questionNumber++;
scoreKeeper.add(
Icon(Icons.check, color: Colors.red),
);
},);
}
},
child: Text(
'False',
),
),
),
),
Row(
children: scoreKeeper,
),
],
);
}
}
**Here is the Question.dart code**
> Question.dart
class Question{ late String questionText; late bool
questionAnswer; Question({required String q, required bool a}) {
questionText=q; questionAnswer=a; } }'
The following _CastError was thrown building MediaQuery(MediaQueryData(size: Size(360.0, 736.0), devicePixelRatio: 3.0, textScaleFactor: 1.0, platformBrightness: Brightness.dark, padding: EdgeInsets.zero, viewPadding: EdgeInsets.zero, viewInsets: EdgeInsets.zero, alwaysUse24HourFormat: false, accessibleNavigation: false, highContrast: false, disableAnimations: false, invertColors: false, boldText: false, navigationMode: traditional)):
type '_CompactLinkedHashSet' is not a subtype of type 'List' in type cast
Change it to this:
List<Question> questionBank=[
Question(q: 'Moon Color is gray',a:false),
Question(q: 'Independence Day of pakistan was 1947',a:true),
Question(q: 'Tesla was the owner of Starlink company',a:false),
]
Use square brackets. Or change your definition to:
Set<Question> questionBank = { ....etc };
I am a beginner and self-learning. I'm using Flutter/Dart to make a quiz app. I am stuck on a portion of my code. I have a list with a map inside. It contains the question, four different choices for the question, and the correct answer (answerIndex).
I want to have the function of when a user selects one of the choices, the button will turn into red or green based on if the answer is correct or incorrect. I'm a bit lost on how to go about this with my current code.
class QuizPage extends StatefulWidget {
#override
_QuizPageState createState() => _QuizPageState();
}
class _QuizPageState extends State<QuizPage> {
static const questions = [
{
'questionText':
'What protein is the principal component of skeletal muscle thick filiaments?',
'answersList': ['Actin', 'Myosin', 'Troponin', 'Tropomyosin'],
'answerIndex': 1,
},
{
'questionText': 'What connective tissue surrounds the entire muscle?',
'answersList': ['Epimysium', 'Perimysium', 'Endomysium', 'Plasmalemma'],
'answerIndex': 0,
},
{
'questionText':
'In skeletal muscle cells, calcium initiates contraction by binding to?',
'answersList': ['Tropomyosin', 'Actin', 'Troponin', 'Myosin'],
'answerIndex': 2,
}
];
int questionNumber = 0;
void answeredQuestion() {
if (questionNumber < questions.length) {
setState(() {
questionNumber += 1;
});
}
}
#override
Widget build(BuildContext context) {
return questionNumber < questions.length
? Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Row(
children: [
Padding(
padding: EdgeInsets.symmetric(
horizontal: 10.0,
vertical: 30.0,
),
),
Text(
'${questionNumber + 1} of ${questions.length}',
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
),
),
],
),
Question(
questionText:
questions[questionNumber]['questionText'].toString(),
),
///Answer Choices///
...(questions[questionNumber]['answersList'] as List<String>)
.map((answer) {
return Answer(
selectedAnswer: answeredQuestion, answerText: answer);
}).toList(),
],
)
: Result();
}
}
Here is my code for the Question
lass Question extends StatelessWidget {
final String questionText;
Question({required this.questionText});
#override
Widget build(BuildContext context) {
return Expanded(
flex: 5,
child: Center(
child: Text(questionText,
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
),
textAlign: TextAlign.center,
),
),
);
}
}
and here is my code for the Answer.
class Answer extends StatelessWidget {
final VoidCallback selectedAnswer;
final String answerText;
Answer({required this.selectedAnswer, required this.answerText});
#override
Widget build(BuildContext context) {
return Expanded(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Container(
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.amber),
),
child: Text(
answerText,
style: TextStyle(
fontSize: 18.0,
),
),
onPressed: selectedAnswer,
),
),
),
);
}
}
You might want to do something like this:
To make this code work, all that was needed was keeping track of the chosen answer and right answer, and passing them down to the Answer widget.
This way, the Answer widget can know wether it was selected, and wether it is the correct answer, and change its Color accordingly.
Also, it is generally preferable to use for() instead of .map in widgets in flutter. Also, to change the button color, the property primary works better.
class QuizPage extends StatefulWidget {
#override
_QuizPageState createState() => _QuizPageState();
}
class _QuizPageState extends State<QuizPage> {
static const questions = [
{
'questionText':
'What protein is the principal component of skeletal muscle thick filiaments?',
'answersList': ['Actin', 'Myosin', 'Troponin', 'Tropomyosin'],
'answerIndex': 1,
},
{
'questionText': 'What connective tissue surrounds the entire muscle?',
'answersList': ['Epimysium', 'Perimysium', 'Endomysium', 'Plasmalemma'],
'answerIndex': 0,
},
{
'questionText':
'In skeletal muscle cells, calcium initiates contraction by binding to?',
'answersList': ['Tropomyosin', 'Actin', 'Troponin', 'Myosin'],
'answerIndex': 2,
}
];
int questionNumber = 0;
// Keep track of the answers that have been chosen.
Map<int, int> selectedAnswers = {};
void answeredQuestion(int questionIndex, int answerIndex) {
if (questionNumber < questions.length) {
setState(() {
questionNumber += 1;
selectedAnswers[questionIndex] = answerIndex;
});
}
}
#override
Widget build(BuildContext context) {
return questionNumber < questions.length
? Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Row(
children: [
Padding(
padding: EdgeInsets.symmetric(
horizontal: 10.0,
vertical: 30.0,
),
),
Text(
'${questionNumber + 1} of ${questions.length}',
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
),
),
],
),
Question(
questionText:
questions[questionNumber]['questionText'].toString(),
),
///Answer Choices///
for (var i = 0; i < (questions[questionNumber]['answersList'] as List<String>).length ; i++) Answer(
selectedAnswer: () => answeredQuestion(questionNumber, i), answerText: answer, isSelected: selectedAnswers?[questionNumber] == i, isCorrectAnswer: questions[questionNumber].answerIndex == i);
}).toList(),
],
)
: Result();
}
}
class Answer extends StatelessWidget {
final VoidCallback selectedAnswer;
final String answerText;
final bool isSelected;
final bool isCorrectAnswer;
Answer({required this.selectedAnswer, required this.answerText, required this.isSelected, required this.isCorrectAnswer});
#override
Widget build(BuildContext context) {
return Expanded(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Container(
child: ElevatedButton(
style: ButtonStyle(primary: () {
if (!isSelected) {
return Colors.amber
}
else if (isCorrectAnswer) {
return Colors.green;
} else {
return Colors.red
}
}
),
child: Text(
answerText,
style: TextStyle(
fontSize: 18.0,
),
),
onPressed: selectedAnswer,
),
),
),
);
}
}