I'm using Flutter-Dart-SQLite to develop a quiz application. Here I have used RadioListTile for radio button functionality. I am passing the text value from an array to this StatefulWidget
.
This is the code I'm using,
import 'package:flutter/material.dart';
import 'package:get/get_state_manager/get_state_manager.dart';
import 'package:loginform_validation_demo/QuizApp/controllers/question_controller.dart';
import 'package:loginform_validation_demo/resource-file/constants.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter/src/material/radio_list_tile.dart';
class OptionRadio extends StatefulWidget {
final String text;
final int index;
final VoidCallback press;
const OptionRadio({
Key key,
this.text,
this.index,
this.press,
}) : super();
@override
OptionRadioPage createState() =>
OptionRadioPage(this.text, this.index, this.press);
}
class OptionRadioPage extends State<OptionRadio> {
final String text;
int index;
final VoidCallback press;
QuestionController controllerCopy =QuestionController();
int id = 1;
int selectedButton = null;
bool _isButtonDisabled;
OptionRadioPage(this.text, this.index, this.press);
@override
void initState() {
_isButtonDisabled = false;
}
int _selected = null;
@override
Widget build(BuildContext context) {
return GetBuilder<QuestionController>(
init: QuestionController(),
builder: (qnController) {
Color getTheRightColor() {
if (qnController.isAnswered) {
if (index == qnController.selectedAns &&
qnController.selectedAns == qnController.correctAns) {
return kBlackColor;
} else if (index == qnController.selectedAns &&
qnController.selectedAns != qnController.correctAns) {
return kBlackColor;
}
}
return kBlackColor;
}
return InkWell(
onTap: press,
child: Container(
child: Row(
children: <Widget>[
Expanded(
child: Container(
// height: 60.0,
child: Theme(
data: Theme.of(context).copyWith(
unselectedWidgetColor: Colors.grey,
disabledColor: Colors.blue),
child: Column(children:
[
RadioListTile(
title: Text(
"${index + 1}. $text",
style: TextStyle(
color: getTheRightColor(), fontSize: 16),
softWrap: true,
),
/*Here the selectedButton which is null initially takes place of value after onChanged. Now, I need to clear the selected button when other button is clicked */
groupValue: selectedButton,
value: index,
activeColor: Colors.green,
onChanged:
(val) async {
debugPrint(
'Radio button is clicked onChanged $val');
setState(() {
debugPrint('Radio button setState $val');
selectedButton = val;
debugPrint('Radio button is clicked onChanged $index');
});
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setInt('intValue', val);
},
toggleable: true,
),
]
),
)),
),
],
),
),
);
});
}
@override
State<StatefulWidget> createState() {
throw UnimplementedError();
}
}
Here the selectedButton which is null initially takes place of value of group value after onChanged
. Now, I need to clear the selected button when the other button is clicked.
I'm guessing I have something done wrong in group value part.
The part where I use OptionRadio,
class QuestionCardWidgetRadio extends StatelessWidget {
OptionRadio optionRadio = OptionRadio();
QuestionCardWidgetRadio({
Key key,
this.note,
this.index,
this.questionLength,
}) : super(key: key);
final BlazorQuiz note;
final int index;
final int questionLength;
bool _isAnswered = false;
bool get isAnswered => this._isAnswered;
int selectedButton;
@override
Widget build(BuildContext context) {
QuestionController _questionController =
Get.put(QuestionController());
debugPrint("Answer Print : ${note.Answer.split(",")}");
return Container(
margin: EdgeInsets.symmetric(horizontal: kDefaultPadding, vertical: 35),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(25),
),
padding: EdgeInsets.all(kDefaultPadding),
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
children: [
...List.generate(
note.Answer.split(",").length,
(index) => OptionRadio(
index: index,
text: note.Answer.split(",")[index],
press: (val) => setState(() {
selectedButton = int.parse(val.toString());
print("$selectedButton");
}),
selectedButton: selectedButton,
// press:
// () =>{
// _isAnswered = true,
// _questionController.checkAns(note, index),
// selectedButton,
// }
),
SingleChildScrollView(
scrollDirection: Axis.vertical,
child: TextButton(
onPressed: () async {
debugPrint("Clicked options : ${note.Answer.isNotEmpty} isAnswered: $isAnswered");
debugPrint('Check Index : ${index} check quiz model Lenght : ${QuizModel.question.length} check note Id : ${note.Id}');
if(index+1 == questionLength){
// score screen
debugPrint('Navigate to score screen');
Text(
"Submit",
style: Theme.of(context)
.textTheme
.button
.copyWith(color: Colors.white),
);
_questionController.scoreNavigation(index, context);
}
else{
if (note.Answer.isNotEmpty == !isAnswered) {
debugPrint('Clicked RadioBtn ${optionRadio.index}');
SharedPreferences prefs = await SharedPreferences.getInstance();
//Return int
int intValue = prefs.getInt('intValue');
debugPrint('Int value from sharedPrefs: $intValue');
_questionController.nextQuestion(note,intValue,"","",[]);
prefs.remove("intValue");
}else{
debugPrint('Click proper option for Radio');
}
}
},
child: Container(
width: double.infinity,
alignment: Alignment.center,
padding: EdgeInsets.all(kDefaultPadding * 0.75),
margin: EdgeInsets.all(37),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10)),
color: Color(ColorData.button)
),
child: Text(
"Next Question",
style: Theme.of(context)
.textTheme
.button
.copyWith(color: Colors.white),
),
),
),
),
],
),
),
);
}
setState(Null Function() param0) {}
}
I get values from an array where the options are separated by comma. "Answer":"Male,Female"