繁体   English   中英

Flutter/Dart - 在 Listview.Builder 中动态控制 CheckboxListTile

[英]Flutter/Dart - Dynamically controlling CheckboxListTile inside Listview.Builder

我正在尝试创建一个列出许多问题的页面。 对于每个问题,我都会有不同的答案。 此刻,每当我 select 一个答案时,其他问题上的相同选项都会同时被选中。 我怎样才能避免这种情况并使每个问题成为自己的实体? 这是我的代码:

      class QuestionScreen extends StatefulWidget {
    
      @override
      _QuestionScreenState createState() => _QuestionScreenState();
    }
    
    class _QuestionScreenState extends State<QuestionScreen> {
      List<bool> _isChecked;
    
   
    final Map<String, Map> questions = {"milk comes from what animal": 
    {"horse": false, "monkey": false, "frog": false, "cow": true}, 
    "what colour is the sea?": 
    {"red": false, "green": false, "blue": true, "yellow": false}};

  @override
  void initState() {
    super.initState();
    _isChecked = List<bool>.filled(questions.values.length, false);
  }

      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(),
          body: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Container(
                child: Text("questions page"),
              ),
              Expanded(
                child: new ListView.builder(
                  itemCount: questions.keys.length,
                  itemBuilder: (BuildContext ctxt, int questionTitleIndex) {
                    return Padding(
                      padding: const EdgeInsets.all(24.0),
                      child: Container(
                        height: MediaQuery.of(context).size.height * 0.45,
                        decoration: BoxDecoration(
                          color: OurTheme().ourCanvasColor,
                          borderRadius: BorderRadius.circular(25),
                        ),
                        child: Column(
                          children: [
                            Text(
                              questions.keys.toList()[questionTitleIndex],
                              style: TextStyle(
                                  color: Colors.white,
                                  fontSize: 24,
                                  fontWeight: FontWeight.w800),
                            ),
                            Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: ListView.builder(
                                shrinkWrap: true,
                                itemCount: questions.values
                                    .toList()[questionTitleIndex]
                                    .keys
                                    .length,
                                itemBuilder:
                                    (BuildContext ctxt, int questionAnswersIndex) {
                                  return Container(
                                    decoration: BoxDecoration(border: Border.all()),
                                    child: CheckboxListTile(
                                      title: Text(
                                        "${questionAnswersIndex + 1}. ${questions.values.toList()[questionTitleIndex].keys.toList()[questionAnswersIndex]}",
                                        style: TextStyle(
                                            color: Colors.white, fontSize: 16),
                                      ),
                                      value: _isChecked[questionAnswersIndex],
                                      controlAffinity:
                                          ListTileControlAffinity.platform,
                                      onChanged: (bool value) {
                                        setState(
                                          () {
                                            _isChecked[questionAnswersIndex] =
                                                value;
                                          },
                                        );
                                      },
                                      activeColor: OurTheme().ourCanvasColor,
                                      checkColor: Colors.white,
                                    ),
                                  );
                                },
                              ),
                            )
                          ],
                        ),
                      ),
                    );
                  },
                ),
              )
            ],
          ),
        );
      }
    }

我在这里看到了一些问题。

首先,因为您需要维护_isChecked中每个questionanswer 将其设为Map<String, String>而不是List<bool>会更有意义。

在其中, key将是问题标题,值将是选定的选项标题。

因此,在您的initState中,您将像这样启动它。

Map<String, String> _isChecked = {}; // Initializing with empty map

@override
void initState() {
  super.initState();
  widget.questions.keys.forEach((key) {


    // For each question we first set the answer as "". means nothing selected.
    _isChecked[key] = "";

    // We then loop over the options of that question to see if any option was already true and set it as the initial answer.
    for (MapEntry entry in widget.questions[key]!.entries) {
      if (entry.value) _isChecked[key] = entry.key;
    }
  });
}

在此之后,您只需更改代码中使用_isChecked变量的位置。

这是完整工作代码的链接。 只需将所有代码替换为链接中的代码即可。

结果。 在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM