I have generated answer buttons and when I click the answer button color is not changing. Can you help me to sort this out. Here all I want is to change the color when ever I click a button. Please help me out since I'm very new to flutter. Thank you very much.
import 'package:flutter/material.dart';
import 'show_question_model.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
class ShowQuestions extends StatefulWidget {
final String subid;
const ShowQuestions({super.key, required this.subid});
@override
State<ShowQuestions> createState() => _ShowQuestionsState(subid);
}
class _ShowQuestionsState extends State<ShowQuestions> {
String subid;
_ShowQuestionsState(this.subid);
List<Question> questionList = [];
int currentQuestionIndex = 0;
int score = 0;
late final Future myFuture;
void initState() {
super.initState();
myFuture = getQuestionData(subid);
}
Future getQuestionData(String subid) async {
var response = await http.get(
Uri.http("www.ananmanan.lk", "app/getQuestionList.php", {'id': subid}));
var jsonData = jsonDecode(response.body);
List<Question> questions = [];
for (var u in jsonData) {
Question question = Question(
u['ques'],
u['ans1'],
u['ans2'],
u['ans3'],
u['ans4'],
u['correct_ans'].toString(),
);
questions.add(question);
}
return questions;
}
//Answer? selectedAnswer;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Question Paper'),
centerTitle: true,
),
body: Container(
child: FutureBuilder(
future: myFuture,
builder: (context, snapshot) {
if (snapshot.data == null) {
return Container(
child: Center(
child: Text('Loading...'),
),
);
} else {
questionList = snapshot.data;
return Container(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 32),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_questionWidget(),
_answerList(),
_nextButton(),
],
),
);
}
},
)),
);
}
_questionWidget() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Question ${currentQuestionIndex 1}/5}',
style: const TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.w600,
),
),
const SizedBox(
height: 20.0,
),
Container(
width: double.infinity,
alignment: Alignment.center,
padding: const EdgeInsets.all(32.0),
decoration: BoxDecoration(
color: Colors.orangeAccent,
borderRadius: BorderRadius.circular(16)),
child: Text(
questionList[currentQuestionIndex].ques,
style: const TextStyle(
color: Colors.white,
fontSize: 18.0,
fontWeight: FontWeight.w600,
),
),
),
],
);
}
_answerList() {
bool isCorrectAns = false;
bool isAns1 = false;
bool isAns2 = false;
bool isAns3 = false;
bool isAns4 = false;
//bool isSelected = answer == selectedAnswer;
// ignore: unrelated_type_equality_checks
// if (questionList[currentQuestionIndex].correctanswer == 1) {
// isCorrectAns = true;
// } else {
// isCorrectAns = false;
// }
if (questionList[currentQuestionIndex].correct_ans == '1') {
isAns1 = true;
} else if (questionList[currentQuestionIndex].correct_ans == '2') {
isAns2 = true;
} else if (questionList[currentQuestionIndex].correct_ans == '3') {
isAns3 = true;
} else if (questionList[currentQuestionIndex].correct_ans == '4') {
isAns4 = true;
}
return Container(
// width: double.infinity,
// margin: const EdgeInsets.symmetric(vertical: 2),
// height: 48,
child: Column(children: [
_answerButton(questionList[currentQuestionIndex].ans1, isAns1),
_answerButton(questionList[currentQuestionIndex].ans2, isAns2),
_answerButton(questionList[currentQuestionIndex].ans3, isAns3),
_answerButton(questionList[currentQuestionIndex].ans4, isAns4),
]),
);
}
Widget _answerButton(String ansText, bool correctans) {
//bool isSelected = answer == selectedAnswer;
bool click = false;
if (ansText != '') {
return Container(
width: double.infinity,
margin: const EdgeInsets.symmetric(vertical: 2),
height: 48,
child: ElevatedButton(
child: Text(ansText),
style: ElevatedButton.styleFrom(
shape: const StadiumBorder(),
primary: click == true ? Colors.orangeAccent : Colors.white,
onPrimary: click == true ? Colors.white : Colors.black,
),
onPressed: () {
if (correctans) {
score ;
}
},
),
);
} else {
return SizedBox.shrink();
}
}
_nextButton() {
bool isLastQuestion = false;
if (currentQuestionIndex == questionList.length - 1) {
isLastQuestion = true;
}
return Container(
width: MediaQuery.of(context).size.width * 0.5,
height: 48,
child: ElevatedButton(
child: Text(isLastQuestion ? 'Submit' : 'Next'),
style: ElevatedButton.styleFrom(
shape: const StadiumBorder(),
primary: Colors.blueAccent,
onPrimary: Colors.white,
),
onPressed: () {
if (isLastQuestion) {
showDialog(context: context, builder: (_) => _showScoreDialog());
} else {
setState(() {
//selectedAnswer = null;
currentQuestionIndex ;
});
}
},
),
);
}
_showScoreDialog() {
bool isPassed = false;
if (score >= questionList.length * 0.6) {
isPassed = true;
}
String title = isPassed ? 'Passed' : 'Failed';
return AlertDialog(
title: Text(
title ' | Score is $score',
style: TextStyle(color: isPassed ? Colors.green : Colors.redAccent),
),
content: ElevatedButton(
child: const Text('Restart'),
onPressed: () {
Navigator.pop(context);
setState(() {
currentQuestionIndex = 0;
score = 0;
//selectedAnswer = null;
});
},
),
);
}
}
Change the button color of the above code
CodePudding user response:
You are not saving the state of the variable click
anywhere. Make sure you do for each "AnswerButton".
CodePudding user response:
Try setting the state again when the button is clicked. Something like this:
child: ElevatedButton(
child: Text(ansText),
style: ElevatedButton.styleFrom(
shape: const StadiumBorder(),
primary: click == true ? Colors.orangeAccent : Colors.white,
onPrimary: click == true ? Colors.white : Colors.black,
),
onPressed: () {
if (correctans) {
score ;
setState((){
click = !click;
)};
CodePudding user response:
Same as Robert Sandberg mentioned before. Each AnswerButton needs to save it's click state for their own. Therefore make a new StatefulWidget AnswerButton.
Here is a quick implementation for this. Insert the new AnswerButton widget for every answer option.
class AnswerButton extends StatefulWidget {
final String text;
final VoidCallback onTap;
AnswerButton({required this.text, required this.onTap});
@override
State<StatefulWidget> createState() {
return _AnswerButtonState();
}
}
class _AnswerButtonState extends State<AnswerButton> {
bool click = false;
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
margin: const EdgeInsets.symmetric(vertical: 2),
height: 48,
child: ElevatedButton(
child: Text(widget.text),
style: ElevatedButton.styleFrom(
shape: const StadiumBorder(),
primary: click == true ? Colors.orangeAccent : Colors.white,
onPrimary: click == true ? Colors.white : Colors.black,
),
onPressed: () {
click = !click;
widget.onTap.call();
},
),
);
}
}
Furthermore you should follow the advices and replace depricated members like 'primary' and 'onPrimary' of ElevatedButton.
CodePudding user response:
primary
andonPrimary
are deprecated afterv3.1.0
Use analogues for them:
- primary -> foregroundColor
- onPrimary -> disabledForegroundColor
- Use
setState
function when you are changing the state variables(click
)
The new version of your widget:
class AnswerButton extends StatefulWidget {
final String text;
final VoidCallback onTap;
const AnswerButton({Key? key, required this.text, required this.onTap}) : super(key: key);
@override
State<StatefulWidget> createState() {
return _AnswerButtonState();
}
}
class _AnswerButtonState extends State<AnswerButton> {
bool click = false;
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
margin: const EdgeInsets.symmetric(vertical: 2),
height: 48,
child: ElevatedButton(
child: Text(widget.text),
style: ElevatedButton.styleFrom(
shape: const StadiumBorder(),
foregroundColor: click == true ? Colors.orangeAccent : Colors.white,
disabledForegroundColor: click == true ? Colors.white : Colors.black,
),
onPressed: () {
setState(() {
click = !click;
widget.onTap.call();
});
},
),
);
}
}