RadioListTile Inside StatefulBuilder not deselecting other options inside RadioListTile

此生再无相见时 提交于 2020-12-15 06:23:06

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!