“对话框”内的列表视图中的复选框无法正常工作

Posted

技术标签:

【中文标题】“对话框”内的列表视图中的复选框无法正常工作【英文标题】:checkbox in a listview inside a 'Dialog' not working in flutter 【发布时间】:2020-04-04 00:52:18 【问题描述】:

我在单击按钮时触发了一个对话框,我想在该对话框中打印一些包含从 firestore 获取的数据的行。 'Dialog' 框有一个 Listview 小部件,我在其中循环浏览我的文档快照以打印行以及它们前面的复选框。基本上我想对使用复选框选择的所有项目执行操作。但是当我点击时,复选框不起作用。

请帮忙!我是新来的颤振。这是我的对话框的完整代码。

  final snapshot = await Firestore.instance
        .collection('students')
        .where('vehicle_code', isEqualTo: _userId)
        .getDocuments(); 
 await showDialog<void>(
      context: context,
      builder: (BuildContext context) 
        bool isChecked = false;
      return Dialog(

      shape:
        RoundedRectangleBorder(borderRadius: new BorderRadius.circular(15)),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[

            Container(
              padding: EdgeInsets.all(12),
              alignment: Alignment.center,
              decoration: BoxDecoration(
                  color: Colors.grey[300],
                  borderRadius: new BorderRadius.only(
                  topLeft: const Radius.circular(15),
                  topRight: const Radius.circular(15)),
              ),
              child: Text(
                "Select Students",
                style: TextStyle(
                    color: Colors.black,
                    fontSize: 18,
                    fontWeight: FontWeight.w600),
              ),
            ),
              Container(
                width: 300,
                height: 400,
                child: ListView(
                  //mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: <Widget>[

                    for(var item in snapshot.documents )
                      //Text(item['first_name'])
                      Row(
                        children: [
                          SizedBox(
                            width: 100.0,
                            height: 100.0,
                            child: Image.asset('assets/newlogo.png'),
                          ),
                          Text(item['first_name']),
                          Checkbox(
                            value: isChecked,
                            onChanged: (bool value) 
                              print(isChecked);
                              setState(() 
                                isChecked = value;
                              );
                            ,
                          ),

                        ],
                      ),

                  ],
                ),

              ),


      Row(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.end,
              children: <Widget>[
                RaisedButton(
                  color: Colors.blue,
                  onPressed: () 
                    Navigator.of(context).pop();
                  ,
                  child: Text(
                    'Okay',
                    style: TextStyle(fontSize: 18.0, color: Colors.white),
                  ),
                ),
                SizedBox(
                  width: 20,
                ),
                RaisedButton(
                  color: Colors.red,
                  onPressed: () 
                    Navigator.of(context).pop();
                  ,
                  child: Text(
                    'Cancel!',
                    style: TextStyle(fontSize: 18.0, color: Colors.white),
                  ),
                )
              ],
            ),

      ],
    ),
    );
    ,
    );

【问题讨论】:

【参考方案1】:

您可以搬出isChecked 并用StatefulBuilder 换行 您仍然需要使用List&lt;bool&gt; isCheckList 来控制您的复选框 但这取决于您的设计

代码sn-p

bool isChecked = false;

      void _incrementCounter() async 
        await showDialog<void>(
            context: context,
            builder: (BuildContext context) 
              return StatefulBuilder(
                builder: (BuildContext context, StateSetter setState) 

                  return Dialog(

工作演示

完整的测试代码

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget 
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  


class MyHomePage extends StatefulWidget 
  MyHomePage(Key key, this.title) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();


class _MyHomePageState extends State<MyHomePage> 
  int _counter = 0;
  List<Map> snapshot = [
    "first_name": "abc",
    "first_name": "def"
  ];
  bool isChecked = false;

  void _incrementCounter() async 
    await showDialog<void>(
        context: context,
        builder: (BuildContext context) 
          return StatefulBuilder(
            builder: (BuildContext context, StateSetter setState) 

              return Dialog(
                shape: RoundedRectangleBorder(
                    borderRadius: new BorderRadius.circular(15)),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: <Widget>[
                    Container(
                      padding: EdgeInsets.all(12),
                      alignment: Alignment.center,
                      decoration: BoxDecoration(
                        color: Colors.grey[300],
                        borderRadius: new BorderRadius.only(
                            topLeft: const Radius.circular(15),
                            topRight: const Radius.circular(15)),
                      ),
                      child: Text(
                        "Select Students",
                        style: TextStyle(
                            color: Colors.black,
                            fontSize: 18,
                            fontWeight: FontWeight.w600),
                      ),
                    ),
                    Container(
                      width: 300,
                      height: 400,
                      child: ListView(
                        //mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                        children: <Widget>[

                          for (var item in snapshot)
                            //Text(item['first_name'])
                            Row(
                              children: [
                                /*SizedBox(
                                  width: 100.0,
                                  height: 100.0,
                                  child: Image.asset('assets/newlogo.png'),
                                ),*/
                                Text(item['first_name']),
                                Checkbox(
                                  value: isChecked,
                                  onChanged: (bool value) 
                                    print(isChecked);
                                    setState(() 
                                      isChecked = value;
                                    );
                                  ,
                                ),
                              ],
                            ),
                        ],
                      ),
                    ),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.end,
                      children: <Widget>[
                        RaisedButton(
                          color: Colors.blue,
                          onPressed: () 
                            Navigator.of(context).pop();
                          ,
                          child: Text(
                            'Okay',
                            style:
                                TextStyle(fontSize: 18.0, color: Colors.white),
                          ),
                        ),
                        SizedBox(
                          width: 20,
                        ),
                        RaisedButton(
                          color: Colors.red,
                          onPressed: () 
                            Navigator.of(context).pop();
                          ,
                          child: Text(
                            'Cancel!',
                            style:
                                TextStyle(fontSize: 18.0, color: Colors.white),
                          ),
                        )
                      ],
                    ),
                  ],
                ),
              );
            ,
          );
        );
    setState(() 
      _counter++;
    );
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  

【讨论】:

非常感谢!但我还有另一个问题。我已经按照您的建议创建了一个布尔列表,但是如何在 foreach 循环中索引 isChecked 数组 更新:我已经使用 C 风格的 for 循环让它工作,但我想一定有一些更好更干净的方法

以上是关于“对话框”内的列表视图中的复选框无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

WebView中的弹出对话框无法显示,但可以在chrome浏览器中正常工作

为啥我无法使用 WM_NCPAINT 刷新对话框,但使用 WM_SIZE 可以正常工作?

带有复选框和自定义适配器的 ListView,片段无法正常工作

无法将部分视图显示为 JQuery Mobile 对话框

将触摸事件委托给另一个视图

多个复选标记附件在 iOS7 中无法正常工作