【问题标题】:update checkbox and return value from dialog in flutter更新复选框并从颤动中的对话框返回值
【发布时间】:2018-10-06 06:30:44
【问题描述】:

我正在尝试将一些城市列表添加到带有复选框的对话框中,以便我需要实现对项目的多次点击。下面给出了我想要做的事情。

onPressed 来自按钮调用 Rest Service,成功后我只显示一个对话框

void showCityDialog(BuildContext context) {
    SimpleDialog dialog = new SimpleDialog(
      title: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          new Text(
            "CITIES",
            style: TextStyle(fontSize: 18.0, color: Colors.black),
            textAlign: TextAlign.center,
          ),
          new RaisedButton(
            onPressed: () {print("clicked");},
            color: Color(0xFFfab82b),
            child: new Text(
              "Done",
              style: TextStyle(color: Colors.white),
            ),)],),
      children: <Widget>[
        Column(
          mainAxisAlignment: MainAxisAlignment.start,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            new Container(
              constraints: BoxConstraints(maxHeight: 500.0),
              child: ListView.builder(
                scrollDirection: Axis.vertical,
                itemCount: cityData.length,
                itemBuilder: (context, position) {
                  return new CheckboxListTile(
                    value: checkboxValueCity,
                    onChanged: (bool value) {
                      setState(() {
                        checkboxValueCity = value;
                      });
                    },
                    activeColor: Color(0xFFfab82b),
                    dense: true,
                    title: Text(
                      cityData[position].city_name,
                      style: TextStyle(fontSize: 16.0, color: Colors.black),
                    ),);},),),],)],);
    showDialog(
        context: context,
        builder: (BuildContext context) {
          return dialog;
        });
  }

checkboxValueCity 是类中的布尔变量,单击 chekboxListItem 我需要将复选框值更新为已选中和未选中。同时需要将该项目添加/删除到该类内的列表中。

但在我的代码中,复选框并没有在每次点击时引用,但是当我关闭该框并再次打开它时,复选框被选中。那么如何从磁贴中获得多次点击以及如何从对话框中返回列表?

【问题讨论】:

    标签: checkbox dart dialog flutter


    【解决方案1】:

    您的对话框必须是StatefulWidget (Flutter Github issue)。跟踪选择状态的成员变量需要在对话框类中。您可以使用回调来使用所选城市的List 更新父类中的成员变量。在SimpleDialogAlertDialog 中使用ListView.builder 似乎也存在一些问题(在Flutter Github 中搜索问题),所以我使用了一个普通的Dialog

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Checkbox Dialog Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(title: 'Flutter Checkbox Dialog Demo'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      bool checkboxValueCity = false;
      List<String> allCities = ['Alpha', 'Beta', 'Gamma'];
      List<String> selectedCities = [];
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          floatingActionButton: FloatingActionButton(
              child: Icon(Icons.add),
              onPressed: () {
                showDialog(
                    context: context,
                    builder: (context) {
                      return _MyDialog(
                          cities: allCities,
                          selectedCities: selectedCities,
                          onSelectedCitiesListChanged: (cities) {
                            selectedCities = cities;
                            print(selectedCities);
                          });
                    });
              }),
        );
      }
    }
    
    class _MyDialog extends StatefulWidget {
      _MyDialog({
        this.cities,
        this.selectedCities,
        this.onSelectedCitiesListChanged,
      });
    
      final List<String> cities;
      final List<String> selectedCities;
      final ValueChanged<List<String>> onSelectedCitiesListChanged;
    
      @override
      _MyDialogState createState() => _MyDialogState();
    }
    
    class _MyDialogState extends State<_MyDialog> {
      List<String> _tempSelectedCities = [];
    
      @override
      void initState() {
        _tempSelectedCities = widget.selectedCities;
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return Dialog(
          child: Column(
            children: <Widget>[
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <Widget>[
                  Text(
                    'CITIES',
                    style: TextStyle(fontSize: 18.0, color: Colors.black),
                    textAlign: TextAlign.center,
                  ),
                  RaisedButton(
                    onPressed: () {
                      Navigator.pop(context);
                    },
                    color: Color(0xFFfab82b),
                    child: Text(
                      'Done',
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                ],
              ),
              Expanded(
                child: ListView.builder(
                    itemCount: widget.cities.length,
                    itemBuilder: (BuildContext context, int index) {
                      final cityName = widget.cities[index];
                      return Container(
                        child: CheckboxListTile(
                            title: Text(cityName),
                            value: _tempSelectedCities.contains(cityName),
                            onChanged: (bool value) {
                              if (value) {
                                if (!_tempSelectedCities.contains(cityName)) {
                                  setState(() {
                                    _tempSelectedCities.add(cityName);
                                  });
                                }
                              } else {
                                if (_tempSelectedCities.contains(cityName)) {
                                  setState(() {
                                    _tempSelectedCities.removeWhere(
                                        (String city) => city == cityName);
                                  });
                                }
                              }
                              widget
                                  .onSelectedCitiesListChanged(_tempSelectedCities);
                            }),
                      );
                    }),
              ),
            ],
          ),
        );
      }
    }
    

    【讨论】:

      【解决方案2】:

      使用StatefulBuilder 仅在 Dialog 内更新小部件。 StatefulBuilder 最适合更新小部​​件树的部分,其中 状态是必需的。

      简单代码sn-p

          void _showDialog() {
          showDialog(
            context: context,
            builder: (context) {
              return StatefulBuilder( // StatefulBuilder
                builder: (context, setState) {
                  return AlertDialog(
                    actions: <Widget>[
                      Container(
                        width: 400,
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.center,
                            children: <Widget>[
                              Text(
                                "Student Attendence",
                                style: TextStyle(fontSize: 20),
                              ),
                              SizedBox(
                                height: 5,
                              ),
                              Container(
                                height: 2,
                                color: Colors.black,
                              ),
                              SizedBox(
                                height: 15,
                              ),
                            CheckboxListTile(
                              value: user1,
                              title: Text("user1"),
                              onChanged: (value){
                                setState(() {
                                  user1=value;
                                });
                              },
                            ),
                              Divider(
                                height: 10,
                              ),
                              CheckboxListTile(
                                value: user2,
                                title: Text("user2"),
                                onChanged: (value){
                                  setState(() {
                                    user2=value;
                                  });
                                },
                              ),
                              Divider(
                                height: 10,
                              ),
                              CheckboxListTile(
                                value: user3,
                                title: Text("user3"),
                                onChanged: (value){
                                  setState(() {
                                    user3=value;
                                  });
                                },
                              ),
                              Divider(
                                height: 10,
                              ),
                              CheckboxListTile(
                                value: user4,
                                title: Text("user4"),
                                onChanged: (value){
                                  setState(() {
                                    user4=value;
                                  });
                                },
                              ),
                              Divider(
                                height: 10,
                              ),
      
                              SizedBox(
                                height: 5,
                              ),
                              Row(
                                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                                children: <Widget>[
                                  Material(
                                    elevation: 5.0,
                                    color: Colors.blue[900],
                                    child: MaterialButton(
                                      padding: EdgeInsets.fromLTRB(
                                          10.0, 5.0, 10.0, 5.0),
                                      onPressed: () {},
                                      child: Text("Save",
                                          textAlign: TextAlign.center,
                                          style: TextStyle(
                                            color: Colors.white,
                                            fontSize: 15,
                                          )),
                                    ),
                                  ),
                                  Material(
                                    elevation: 5.0,
                                    color: Colors.blue[900],
                                    child: MaterialButton(
                                      padding: EdgeInsets.fromLTRB(
                                          10.0, 5.0, 10.0, 5.0),
                                      onPressed: () {
                                        setState(() {
                                          Navigator.of(context).pop();
                                        });
                                      },
                                      child: Text("Cancel",
                                          textAlign: TextAlign.center,
                                          style: TextStyle(
                                            color: Colors.white,
                                            fontSize: 15,
                                          )),
                                    ),
                                  ),
                                  Material(
                                    elevation: 5.0,
                                    color: Colors.blue[900],
                                    child: MaterialButton(
                                      padding: EdgeInsets.fromLTRB(
                                          10.0, 5.0, 10.0, 5.0),
                                      onPressed: () {},
                                      child: Text("Select All",
                                          textAlign: TextAlign.center,
                                          style: TextStyle(
                                            color: Colors.white,
                                            fontSize: 15,
                                          )),
                                    ),
                                  ),
                                ],
                              )
                            ],
                          ))
                    ],
                  );
                },
              );
            },
          );
        }
      

      例子

      【讨论】:

        【解决方案3】:

        虽然 Albert 的回答有效,但您无需经历所有这些。只需用 StatefulBuilder 包装 content:,瞧! https://api.flutter.dev/flutter/widgets/StatefulBuilder-class.html.

        注意:声明要更改的变量的位置很重要。

        【讨论】:

          【解决方案4】:

          我稍微修改了您的代码,我希望当用户检查列表时,列表不会更新到主视图,但当用户单击“更新”按钮时会更新。 但是有些方法,它不起作用。你能检查一下吗? 非常感谢

          import 'package:flutter/material.dart';
          
          void main() => runApp(MyApp());
          
          class MyApp extends StatelessWidget {
            @override
            Widget build(BuildContext context) {
              return MaterialApp(
                title: 'Flutter Checkbox Dialog Demo',
                theme: ThemeData(
                  primarySwatch: Colors.blue,
                ),
                home: MyHomePage(title: 'Flutter Checkbox Dialog Demo'),
              );
            }
          }
          
          class MyHomePage extends StatefulWidget {
            MyHomePage({Key key, this.title}) : super(key: key);
            final String title;
          
            @override
            _MyHomePageState createState() => _MyHomePageState();
          }
          
          class _MyHomePageState extends State<MyHomePage> {
            bool checkboxValueCity = false;
            List<String> allCities = ['Alpha', 'Beta', 'Gamma'];
            List<String> selectedCities = [];
            List<String> selectedCitiesTemp = [];
          
            @override
            Widget build(BuildContext context) {
              return Scaffold(
                appBar: AppBar(
                  title: Text("App Bar"),
                ),
                body: Center(
                  child: Column(
                    children: <Widget>[
                      _list(),
                      RaisedButton(
                        child: Text("Update From TMP List"),
                        onPressed: () {
                          setState(() {
                            selectedCities = selectedCitiesTemp;
                          });
                        },
                      )
                    ],
                  ),
                ),
                floatingActionButton: FloatingActionButton(
                    child: Icon(Icons.add),
                    onPressed: () {
                      showDialog(
                          context: context,
                          builder: (BuildContext context) {
                            return _MyDialog(
                              cities: allCities,
                              selectedCities: selectedCities,
                              onSelectedCitiesListChanged: (cities) {
                                setState(() {
                                  selectedCitiesTemp = cities;
                                });
                              },
                            );
          
                          });
                    }),
              );
            }
            Widget _list() {
              List<Widget> list = [];
              for(String item in selectedCities) {
                list.add(ListTile(
                  title: Text(item),
                ));
              }
              return Column(
                children: list
              );
            }
          }
          
          class _MyDialog extends StatefulWidget {
            _MyDialog({
              this.cities,
              this.selectedCities,
              this.onSelectedCitiesListChanged,
            });
          
            final List<String> cities;
            final List<String> selectedCities;
            final ValueChanged<List<String>> onSelectedCitiesListChanged;
          
            @override
            _MyDialogState createState() => _MyDialogState();
          }
          
          class _MyDialogState extends State<_MyDialog> {
            List<String> _tempSelectedCities = [];
          
            @override
            void initState() {
              _tempSelectedCities = widget.selectedCities;
              super.initState();
            }
          
            @override
            Widget build(BuildContext context) {
              return Dialog(
                child: Column(
                  children: <Widget>[
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: <Widget>[
                        Text(
                          'CITIES',
                          style: TextStyle(fontSize: 18.0, color: Colors.black),
                          textAlign: TextAlign.center,
                        ),
                      ],
                    ),
                    Expanded(
                      child: ListView.builder(
                          itemCount: widget.cities.length,
                          itemBuilder: (BuildContext context, int index) {
                            final cityName = widget.cities[index];
                            return Container(
                              child: CheckboxListTile(
                                  title: Text(cityName),
                                  value: _tempSelectedCities.contains(cityName),
                                  onChanged: (bool value) {
                                    if (value) {
                                      if (!_tempSelectedCities.contains(cityName)) {
                                        setState(() {
                                          _tempSelectedCities.add(cityName);
                                        });
                                      }
                                    } else {
                                      if (_tempSelectedCities.contains(cityName)) {
                                        setState(() {
                                          _tempSelectedCities.removeWhere(
                                              (String city) => city == cityName);
                                        });
                                      }
                                    }
                                    widget.onSelectedCitiesListChanged(_tempSelectedCities);
                                  }),
                            );
                          }),
                    ),
                  ],
                ),
              );
            }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2020-06-27
            • 2021-11-09
            • 1970-01-01
            • 1970-01-01
            • 2022-11-10
            • 2012-02-01
            相关资源
            最近更新 更多