【问题标题】:How can I handle a list of checkboxes dynamically created in flutter?如何处理在颤动中动态创建的复选框列表?
【发布时间】:2021-08-06 23:35:09
【问题描述】:

使用颤振,我试图用一些文本和旁边的自定义复选框构建一个值列表。点击文本或复选框上的任意位置应显示启用状态,再次点击应禁用它。我不确定如何分别处理每个复选框的状态。我也尝试使用 CheckBoxListTile,但我不确定如何实现我想要的。有人可以提供任何例子吗?

【问题讨论】:

    标签: flutter


    【解决方案1】:

    这是CheckboxListTile 的一些示例代码。您可以在gallery 中找到更多示例。

    import 'package:flutter/material.dart';
    
    class Demo extends StatefulWidget {
      @override
      DemoState createState() => new DemoState();
    }
    
    class DemoState extends State<Demo> {
      Map<String, bool> values = {
        'foo': true,
        'bar': false,
      };
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(title: new Text('CheckboxListTile demo')),
          body: new ListView(
            children: values.keys.map((String key) {
              return new CheckboxListTile(
                title: new Text(key),
                value: values[key],
                onChanged: (bool value) {
                  setState(() {
                    values[key] = value;
                  });
                },
              );
            }).toList(),
          ),
        );
      }
    }
    
    void main() {
      runApp(new MaterialApp(home: new Demo(), debugShowCheckedModeBanner: false));
    }
    

    【讨论】:

    • 当您创建地图时,您正在对其进行硬编码(使其不是动态的)。例如,想象创建一个任务列表(可以是 1 到 50 个任务)。你能改进你的答案吗?
    • @pedro_bb7 - 这不是一个合理的要求。这个答案完美地说明了相关细节 - 使用易于更改的值集合。显示演示如何查询的代码(例如从数据库中)会使答案复杂化而不会增加好处。
    【解决方案2】:

    我认为它会按您的意愿工作。它还将所有选中的复选框值存储到List 变量中。所以你只需将这段代码放在 main.dart 文件中并执行以检查它是如何工作的。

    import 'package:flutter/material.dart';
    void main() => runApp(new MyApp());
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: 'Flutter Demo',
          theme: new ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: new MyHomePage(title: 'Multi-Select & Unselect Checkbox in Flutter'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
      final String title;
    
      @override
      _MyHomePageState createState() => new _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      List _selecteCategorys = List();
    
      Map<String, dynamic> _categories = {
        "responseCode": "1",
        "responseText": "List categories.",
        "responseBody": [
          {"category_id": "5", "category_name": "Barber"},
          {"category_id": "3", "category_name": "Carpanter"},
          {"category_id": "7", "category_name": "Cook"}
        ],
        "responseTotalResult":
            3 // Total result is 3 here becasue we have 3 categories in responseBody.
      };
    
      void _onCategorySelected(bool selected, category_id) {
        if (selected == true) {
          setState(() {
            _selecteCategorys.add(category_id);
          });
        } else {
          setState(() {
            _selecteCategorys.remove(category_id);
          });
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(
            title: new Text(widget.title),
          ),
          body: ListView.builder(
              itemCount: _categories['responseTotalResult'],
              itemBuilder: (BuildContext context, int index) {
                return CheckboxListTile(
                  value: _selecteCategorys
                      .contains(_categories['responseBody'][index]['category_id']),
                  onChanged: (bool selected) {
                    _onCategorySelected(selected,
                        _categories['responseBody'][index]['category_id']);
                  },
                  title: Text(_categories['responseBody'][index]['category_name']),
                );
              }),  
        );
      }
    }
    

    【讨论】:

    • 在此我顶部有“重置”按钮,要清除复选框,我该如何处理。请您帮帮我。
    • @ShangariC 在重置情况下,您必须在 setState() 下将此“_selecteCategorys”设为空白
    • 这需要更新以确保空安全.. 它不起作用
    【解决方案3】:

    使用列表包含返回布尔值。

    这里是例子

    List<int> selectedList = [];
    List<Widget> mList; //you can't add equal
    createMenuWidget(Course courses) {
      for (int b = 0; b < courses.length; b++) {
        Map cmap = courses[b];
        mList.add(CheckboxListTile(
          onChanged: (bool value){
            setState(() {
              if(value){
                selectedList.add(cmap[course_id]);
              }else{
                selectedList.remove(cmap[course_id]);
              }
            });
          },
          value: selectedList.contains(cmap[course_id]),
          title: new Text(cmap[course_name]),
        ));
      }
    }
    

    【讨论】:

      【解决方案4】:

      请使用包 grouped_buttons。
      它支持复选框和收音机。
      https://pub.dartlang.org/packages/grouped_buttons

      CheckboxGroup(
            labels: <String>[
              "Sunday",
              "Monday",
              "Tuesday",
              "Wednesday",
              "Thursday",
              "Friday",
              "Saturday",
            ],
            disabled: [
              "Wednesday",
              "Friday"
            ],
            onChange: (bool isChecked, String label, int index) => print("isChecked: $isChecked   label: $label  index: $index"),
            onSelected: (List<String> checked) => print("checked: ${checked.toString()}"),
          ),
      

      这里有完整的用法示例https://github.com/akshathjain/grouped_buttons/blob/master/example/lib/main.dart

      和作者实现的逻辑 https://github.com/akshathjain/grouped_buttons/blob/master/lib/src/checkbox_group.dart

      基本上,作者使用两个字符串列表来控制选择和取消选择

      void onChanged(bool isChecked, int i){
        bool isAlreadyContained = _selected.contains(widget.labels.elementAt(i));
      
        if(mounted){
         setState(() {
          if(!isChecked && isAlreadyContained){
            _selected.remove(widget.labels.elementAt(i));
          }else if(isChecked && !isAlreadyContained){
            _selected.add(widget.labels.elementAt(i));
          }
      
          if(widget.onChange != null) widget.onChange(isChecked, widget.labels.elementAt(i), i);
          if(widget.onSelected != null) widget.onSelected(_selected);
         });
       }
      }
      

      【讨论】:

        【解决方案5】:

        使用 chekboxListTile

        这里是示例代码

            @override
            Widget build(BuildContext context) {
              return Center(
                child: CheckboxListTile(
                  title: Text('Check me'),
          );
            }
        

        顺便说一句,你也可以在 Flutter 的 ListView 中添加复选框。应用示例如下-

        Main.dart

        import 'package:flutter/material.dart';
        import 'checkbox_in_listview_task-7.dart';
        
        void main() => runApp(MyApp());
        
        class MyApp extends StatelessWidget {
          @override
          Widget build(BuildContext context) {
            return MaterialApp(
              title: 'Flutter Demo',
              debugShowCheckedModeBanner: false,
              theme: ThemeData(primarySwatch: Colors.blue,
              ),
        home: CheckBoxInListview(),
            );
          }
        }
        

        checkbox_in_listview_task.dart

        import 'package:flutter/material.dart';
        
        class CheckBoxInListview extends StatefulWidget {
          @override
          _CheckBoxInListviewState createState() => _CheckBoxInListviewState();
        }
        
        class _CheckBoxInListviewState extends State<CheckBoxInListview> {
          bool _isChecked = true;
        
          List<String> _texts = [
            "InduceSmile.com," "Flutter.io",
            "google.com",
            "youtube.com",
            "yahoo.com",
            "gmail.com"
          ];
          @override
          Widget build(BuildContext context) {
        return Scaffold(
              appBar: AppBar(
                title: Text("CheckBox in ListView Example"),
              ),
              body: ListView(
                padding: EdgeInsets.all(8.0),
                children: _texts.map((text) => CheckboxListTile(
                  title: Text(text),
                   value: _isChecked,
                      onChanged: (val) {
                      setState(() {
                       _isChecked = val;
        
                    });
                  },
                )).toList(),
              ),
            );
          }
        }
        

        这是输出

        【讨论】:

          【解决方案6】:

          这里是怎么做的

          import 'package:flutter/material.dart';
          
          class RegisterFragments extends StatefulWidget {
            RegisterFragments({Key key, this.step}) : super(key: key);
            final int step;
          
            _RegisterFragmentsState createState() => _RegisterFragmentsState();
          }
          
          class _RegisterFragmentsState extends State<RegisterFragments> {
            Map<String, bool> values = {"abc": false, "def": true, "ghi": false};
            List<String> _do = ['One', 'Two', 'Free', 'Four'];
            String _dropdownValue = 'One';
          
            @override
            Widget build(BuildContext context) {
              switch (widget.step) {
                case 0:
                  return buildDo();
                  break;
                case 1:
                  return Container(
                    child: ListView.builder(
                      shrinkWrap: true,
                      itemCount: values.length,
                      itemBuilder: (BuildContext context, int index) {
                        switch (widget.step) {
                          case 0:
                            return buildDo();
                            break;
                          case 1:
                            return buildService(context, index);
                            break;
                          default:
                            return Container();
                            break;
                        }
                      },
                    ),
                  );
                  break;
                default:
                  return Container();
                  break;
              }
            }
          
            Widget buildService(BuildContext context, int index) {
              String _key = values.keys.elementAt(index);
          
              return Container(
                child: Card(
                  child: CheckboxListTile(
                    title: Text(_key),
                    onChanged: (bool value) {
                      setState(() {
                        values[_key] = value;
                      });
                    },
                    value: values[_key],
                  ),
                ),
              );
            }
          
            Widget buildDo() {
              return DropdownButton<String>(
                isExpanded: true,
                hint: Text("Service"),
                items: _do.map<DropdownMenuItem<String>>((String value) {
                  return DropdownMenuItem<String>(
                    value: value,
                    child: Text(value),
                  );
                }).toList(),
                onChanged: (String newValue) {
                  setState(() {
                    this._dropdownValue = newValue;
                  });
                },
                value: _dropdownValue,
              );
            }
          }
          

          【讨论】:

          • 在代码旁边的一些 cmets 和解释总是更能指导您的答案的发布者和读者。
          【解决方案7】:

          使用 CheckBox 使用动态数据列表执行此操作的简单方法。

          List<String>data= ["Mathew","Deon","Sara","Yeu"];
          List<String> userChecked = [];
          
          ListView.builder(
              itemCount: data.length,
              itemBuilder: (context, i) {
                return ListTile(
                  title: Text(
                      data[i])
                  trailing:Checkbox(
                          value: userChecked.contains(data[i]),
                          onChanged: (val) {
                            _onSelected(val, data[i]);
                          },
                        )
                      //you can use checkboxlistTile too
                );
              })
          // now we write the functionality to check and uncheck it!!
          
          void _onSelected(bool selected, String dataName) {
          if (selected == true) {
            setState(() {
              userChecked.add(dataName);
            });
          } else {
            setState(() {
              userChecked.remove(dataName);
            });
          }
          

          }

          它完成了!... 享受飘飘... 竖起大拇指,因为它会为你工作! :P

          【讨论】:

          • 让我知道您面临什么问题!所以,我可以帮你写代码!!
          【解决方案8】:

          屏幕截图(Null 安全)


          代码:

          class _MyPageState extends State<MyPage> {
            final Map<String, bool> _map = {};
            int _count = 0;
          
            @override
            Widget build(BuildContext context) {
              return Scaffold(
                floatingActionButton: FloatingActionButton(
                  child: Icon(Icons.add),
                  onPressed: () => setState(() => _map.addEntries([MapEntry('Checkbox #${++_count}', false)])),
                ),
                body: ListView(
                  children: _map.keys
                      .map(
                        (key) => CheckboxListTile(
                          value: _map[key],
                          onChanged: (value) => setState(() => _map[key] = value!),
                          subtitle: Text(key),
                        ),
                      )
                      .toList(),
                ),
              );
            }
          }
          

          【讨论】:

            【解决方案9】:

            如果您使用 CheckBoxGroup 或任何类似的 AND 位于滑块内,请不要忘记将其放入 StatefulBuilder:

                return StatefulBuilder(// StatefulBuilder
                builder: (context, setState) {
              return CheckboxGroup(
                orientation: GroupedButtonsOrientation.HORIZONTAL,
                margin: const EdgeInsets.only(left: 12.0),
                onSelected: (List selected) => setState(() {
                  _checked = selected;
                }),
                labels: teamWorkoutDays,
                checked: _checked,
                itemBuilder: (Checkbox cb, Text txt, int i) {
                  return Column(
                    children: <Widget>[
                      Icon(Icons.polymer),
                      cb,
                      txt,
                    ],
                  );
                },
              );
            });
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2021-03-05
              • 1970-01-01
              • 2016-06-16
              • 1970-01-01
              • 1970-01-01
              • 2016-12-21
              • 2012-10-31
              • 1970-01-01
              相关资源
              最近更新 更多