StatefulBuilder内部的RadioListTile不取消选择RadioListTile内部的其他选项 [英] RadioListTile Inside StatefulBuilder not deselecting other options inside RadioListTile

查看:53
本文介绍了StatefulBuilder内部的RadioListTile不取消选择RadioListTile内部的其他选项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个函数,其中在该函数中创建了不同的小部件,我为问题中每个单选类型的答案创建了一个radioListTile.(遍历所有答案,并为每个答案创建radioListTile).

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).

我已将此radioListtile包裹在statefulBuilder中,以使其不会重新创建或影响整个屏幕,并使用setstate方法更改/设置值.

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.

问题是当我在radioListTile中选择任何其他选项/值时,它不会取消选择先前的选项(意味着我可以在radioListTile中选择所有选项).

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).

请在下面检查我的代码以创建小部件.

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;
  }

生成地图的代码(将此作为我存储答案/选择的位置)

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);
      }
    }
  }

注意:如果我删除answerWidget.add(StatefulBuilder(...)),它将使整个屏幕得以重建(它确实解决了我的选择问题).如果从最后一个问题中选择一个选项,它将再次出现在顶部.

推荐答案

创建用于处理无线电图块状态的单独方法,并将该状态作为参数传递给此方法,例如

Create a separate method for handling radio tile state and pass the state as parameter to this method e.g

List<RadioListTile> generateRadioTile(var objQuestion, StateSetter setState){
List<RadioListTile> radioList = [];
for (Answer ans in objQuestion.answers) {
  var index = listAnswers.indexWhere((pair) => pair['key'] == objQuestion.questionId);
  // fetching answer index
  var ansIndex = listAnswers[index]['answer'].indexWhere((pair) => pair['key'] == ans.answerId);
  radioList.add(RadioListTile(
    // key: _key,
    title: Text(ans.answerText),
    value: listAnswers[index]['answer'][ansIndex]['key'],
    groupValue: listAnswers[index]['selectedValue'],
    onChanged: (val) {
      setState(() {
        // making all other answer option selected value to false
        listAnswers[index]['answer'].asMap().forEach(
                (index, keyPair) => keyPair['value'] = false);

        // making current answer option selected value to true
        listAnswers[index]['answer'][ansIndex]['value'] =
        true;

        // setting current selected value to selected answer answerId which is key value
        listAnswers[index]['selectedValue'] = val;

        // printing value for debugging
        print('val: ' + val.toString());
        print('ans_index: ' + ansIndex.toString());
        print('value: ' +
            listAnswers[index]['answer'][ansIndex]['value']
                .toString());
        print('Answer array values :-');
        listAnswers[index]['answer'].asMap().forEach(
                (index, keyPair) => print(keyPair['value']));

        // working with the visibility
        processAnswerLogic(ans.answerLogic);
      });
    },
    secondary: const Icon(Icons.check),
    activeColor: Color.fromRGBO(223, 0, 61, 1),
  ));
}
return radioList;}

并在switch语句中更改您的代码,如下所示:

and in switch statement change your code as below:

case ("RADIO"): // if answer type is equal to radio (majority of answers are radio)

    answerWidget.add(StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return Container(
              child: Padding(
                  padding: EdgeInsets.all(10.0),
                  child: Column(
                    children: generateRadioTile(objQuestion, setState),
                  )));
        }));
    return answerWidget;
    break;

这篇关于StatefulBuilder内部的RadioListTile不取消选择RadioListTile内部的其他选项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆