Home > OS >  How to select one checkbox in listView inside listview in Flutter
How to select one checkbox in listView inside listview in Flutter

Time:09-27

how to select one checkbox in each answer for each question. so that each question can only be chosen one answer. this is my data and this is my code

This is data example:

    List<dynamic> survey = [
  {
    "id": 1,
    "question":"Question1",
    "answer": [
      {"id": 1, "name": "Option A"},
      {"id": 2, "name": "Option B"},
      {"id": 3, "name": "Option C"},
      {"id": 4, "name": "Option D"}
    ],
  },
  {
    "id": 2,
    "question":
        "Question2",
    "answer": [
      {"id": 1, "name": "Option A"},
      {"id": 2, "name": "Option B"},
      {"id": 3, "name": "Option C"},
      {"id": 4, "name": "Option D"}
    ],
  },
];

This is my code:

   bool isSelected = false;

  onSelected(value) {
    setState(() {
      isSelected = value!;
    });
  }

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      shrinkWrap: true,
      itemCount: survey.length,
      itemBuilder: (BuildContext context, int index) {
        var number = index   1;
        var listAnswer = survey[index]["answer"];
        return Container(
          padding: EdgeInsets.all(10),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              SizedBox(
                width: MediaQuery.of(context).size.width * 0.9,
                child: Text(
                  survey[index]["question"],
                  maxLines: 5,
                  overflow: TextOverflow.ellipsis,
                ),
              ),
              SizedBox(height: 10),
              ListView.builder(
                shrinkWrap: true,
                itemCount: listAnswer.length,
                itemBuilder: (BuildContext context, int index) {
                  return Container(
                    margin: EdgeInsets.only(bottom: 10),
                    child: ListTile(
                      title: Text(listAnswer[index]["name"]),
                      trailing: Checkbox(
                        checkColor: Colors.white,
                        value: isSelected,
                        shape: CircleBorder(),
                        onChanged: (bool? value) {
                          onSelected(value);
                        },
                      ),
                    ),
                  );
                },
              )
            ],
          ),
        );
      },
    );
  }

CodePudding user response:

It would be easier with model class. I am using a map to store the selected answer.

  Map<String, int> selectedAnswer = {};

Method checking whether current answer is selected or not.

  bool isSelected(String qustion, int answerID) {
    if (selectedAnswer.containsKey(qustion) &&
        selectedAnswer[qustion] == answerID) {
      return true;
    }
    return false;
  }

And switching value

onChanged: (bool? value) {
  if (_isSelected) {
    selectedAnswer[question] =
        listAnswer[index]["id"];
  } else {
    selectedAnswer
        .addAll({question: listAnswer[index]["id"]});
  }
  setState(() {});
},

Full widget.

class TEL extends StatefulWidget {
  const TEL({super.key});

  @override
  State<TEL> createState() => _TELState();
}

class _TELState extends State<TEL> {
  List<dynamic> survey = [
    {
      "id": 1,
      "question": "Question1",
      "answer": [
        {"id": 1, "name": "Option A"},
        {"id": 2, "name": "Option B"},
        {"id": 3, "name": "Option C"},
        {"id": 4, "name": "Option D"}
      ],
    },
    {
      "id": 2,
      "question": "Question2",
      "answer": [
        {"id": 1, "name": "Option A"},
        {"id": 2, "name": "Option B"},
        {"id": 3, "name": "Option C"},
        {"id": 4, "name": "Option D"}
      ],
    },
  ];

  Map<String, int> selectedAnswer = {};

  bool isSelected(String qustion, int answerID) {
    if (selectedAnswer.containsKey(qustion) &&
        selectedAnswer[qustion] == answerID) {
      return true;
    }
    return false;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView.builder(
        shrinkWrap: true,
        padding: const EdgeInsets.all(8),
        itemCount: survey.length,
        itemBuilder: (BuildContext context, int index) {
          var number = index   1;

          final question = survey[index]["question"];

          List<Map> listAnswer = survey[index]["answer"];

          return Container(
            padding: EdgeInsets.all(10),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                SizedBox(
                  width: MediaQuery.of(context).size.width * 0.9,
                  child: Text(
                    question,
                    maxLines: 5,
                    overflow: TextOverflow.ellipsis,
                  ),
                ),
                SizedBox(height: 10),
                ListView.builder(
                  shrinkWrap: true,
                  itemCount: listAnswer.length,
                  itemBuilder: (BuildContext context, int index) {
                    final bool _isSelected =
                        isSelected(question, listAnswer[index]["id"]);
                    return Container(
                      margin: EdgeInsets.only(bottom: 10),
                      child: ListTile(
                        title: Text(listAnswer[index]["name"].toString()),
                        trailing: Checkbox(
                          checkColor: Colors.white,
                          value: _isSelected,
                          shape: CircleBorder(),
                          onChanged: (bool? value) {
                            if (_isSelected) {
                              selectedAnswer[question] =
                                  listAnswer[index]["id"];
                            } else {
                              selectedAnswer
                                  .addAll({question: listAnswer[index]["id"]});
                            }
                            setState(() {});
                          },
                        ),
                      ),
                    );
                  },
                )
              ],
            ),
          );
        },
      ),
    );
  }
}
  • Related