问题
I created a function in which I am creating different widgets in that function I am creating a radioListTile for each answer of type radio inside a question. (looping through all the answers and created radioListTile for each answer).
I have wrapped this radioListtile inside a statefulBuilder so that it don't recreates or effect the whole screen and used setstate method to change/set the value.
the problem is when I select any other option/value inside this radioListTile it does not deselects the previous option (means I can select all the options inside the radioListTile).
please check my code below for the widget creation.
List<Widget> getAnswerWidget(Question objQuestion) {
// list of all answers inside a question
List<Answer> answerList = objQuestion.answers;
// list of widgets for each question
List<Widget> answerWidget = [];
// fetching answer type for switch case inside generating answers method
var answerType = answerList[0].answerType.toUpperCase();
switch (answerType) {
case ("TEXT"): // if answer type is equal to text
var index = listAnswers
.indexWhere((pair) => pair['Key'] == objQuestion.questionId);
answerWidget.add(StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Container(
child: Padding(
padding: EdgeInsets.all(10.0),
child: new Theme(
data: new ThemeData(
primaryColor: Color.fromRGBO(223, 0, 61, 1),
primaryColorDark: Color.fromRGBO(223, 0, 61, 1),
),
child: TextField(
decoration: new InputDecoration(
border: new OutlineInputBorder(
borderSide: new BorderSide(
color: Color.fromRGBO(223, 0, 61, 1))),
hintText: 'This is a question hint',
helperText: 'this is a helper text.',
labelText: 'Enter text',
prefixIcon: const Icon(
Icons.question_answer,
color: Color.fromRGBO(223, 0, 61, 1),
),
prefixText: ' ',
suffixText: 'suffix',
suffixStyle: const TextStyle(
color: Color.fromRGBO(223, 0, 61, 1))),
),
),
),
);
}));
return answerWidget;
break;
case ("CHECKBOX"): // if answer type is equal to checkbox
for (Answer ans in objQuestion.answers) {
var index =
listAnswers.indexWhere((pair) => pair['Key'] == ans.answerId);
answerWidget.add(StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Container(
child: Padding(
padding: EdgeInsets.all(10.0),
child: CheckboxListTile(
title: Text(ans.answerText),
value: listAnswers[index]['value'],
onChanged: (val) {
setState(() {
listAnswers[index]['value'] = val;
print(listAnswers[index]['value']);
});
},
secondary: const Icon(Icons.check),
),
));
}));
}
return answerWidget;
break;
case ("RADIO"): // if answer type is equal to radio (majority of answers are radio)
var index = listAnswers
.indexWhere((pair) => pair['Key'] == objQuestion.questionId);
for (Answer ans in objQuestion.answers) {
answerWidget.add(StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Container(
child: Padding(
padding: EdgeInsets.all(10.0),
child: RadioListTile(
groupValue: listAnswers[index]['value'],
title: Text(ans.answerText),
value: ans.answerId,
onChanged: (val) {
setState(() {
listAnswers[index]['value'] = val;
// debug
print(
'listValue: ' + listAnswers[index]['value'].toString());
print('index: ' + index.toString());
});
},
selected: listAnswers[index]['value'] == ans.answerId,
secondary: const Icon(Icons.child_care),
),
));
}));
}
return answerWidget;
break;
case ("OPTION"): // if answer type is equal to dropdown/select
var index = listAnswers
.indexWhere((pair) => pair['Key'] == objQuestion.questionId);
List<DropdownMenuItem> _dropdownItems = [];
for (var i = 0; i < answerList.length; i++) {
_dropdownItems.add(DropdownMenuItem(
value: answerList[i].answerId,
child: Text(answerList[i].answerText)));
}
answerWidget.add(StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Container(
child: Padding(
padding: EdgeInsets.all(10.0),
child: DropdownButton(
hint: Text('Please Select'),
items: _dropdownItems,
onChanged: (value) {
setState(() {
listAnswers[index]['value'] = value;
print('value:' + value.toString());
});
}),
),
);
}));
return answerWidget;
break;
case ("DATE"): // if answer type is equal to date
var index = listAnswers
.indexWhere((pair) => pair['Key'] == objQuestion.questionId);
answerWidget.add(StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Container(
child: Padding(
padding: EdgeInsets.all(10.0),
child: MyTextFieldDatePicker(
// custom widget inside utils folder
labelText: "Date",
prefixIcon: Icon(Icons.date_range),
suffixIcon: Icon(Icons.arrow_drop_down),
lastDate: DateTime.now().add(Duration(days: 366)),
firstDate: DateTime.now().add(Duration(days: -366)),
initialDate: DateTime.now().add(Duration(days: 1)),
onDateChanged: (selectedDate) {
listAnswers[index]['value'] = selectedDate;
})));
}));
return answerWidget;
break;
} // end switch answer type cases
return answerWidget;
}
code for generation map (consider this as a location where I am storing answers/selections)
void generateAnswers(List<Question> objQuestions) {
for (int i = 0; i < objQuestions.length; i++) {
if (objQuestions[i].answers[0].answerType.toUpperCase() == 'CHECKBOX') {
for (Answer ans in objQuestions[i].answers) {
var keyPair = {
'Key': ans.answerId,
'value': false,
};
listAnswers.add(keyPair);
}
} else if (objQuestions[i].answers[0].answerType.toUpperCase() ==
'RADIO') {
var keyPair = {
'Key': objQuestions[i].questionId,
'value': 0,
};
listAnswers.add(keyPair);
} else if (objQuestions[i].answers[0].answerType.toUpperCase() ==
'TEXT') {
var keyPair = {
'Key': objQuestions[i].questionId,
'value': "",
};
listAnswers.add(keyPair);
} else if (objQuestions[i].answers[0].answerType.toUpperCase() ==
'OPTION') {
var keyPair = {
'Key': objQuestions[i].questionId,
'value': null,
};
listAnswers.add(keyPair);
} else if (objQuestions[i].answers[0].answerType.toUpperCase() ==
'DATE') {
var keyPair = {
'Key': objQuestions[i].questionId,
'value': TimeOfDay.now(),
};
listAnswers.add(keyPair);
}
}
}
Note: If I remove answerWidget.add(StatefulBuilder(...)) it will make the whole screen to rebuild (it does solve my selection problem). And if select an option from the last question it will take to the top again.
来源:https://stackoverflow.com/questions/64029980/radiolisttile-inside-statefulbuilder-not-deselecting-other-options-inside-radiol