【问题标题】:Handle the list of dynamic checkboxes when the widget is added on button click in flutter在颤动中单击按钮时添加小部件时处理动态复选框列表
【发布时间】:2021-01-14 09:32:23
【问题描述】:

单击添加按钮时,会复制相同的小部件。该小部件包含可多选的复选框列表。我能够复制小部件,但是根据小部件的索引处理复选框时遇到了问题。在下图中,复选框选中状态与新的添加小部件一起复制。

我已经实现如下:

根据添加按钮点击构建小部件

  ListView.builder(
                  itemCount: counting,
                  shrinkWrap: true,
                  physics: const NeverScrollableScrollPhysics(),
                  itemBuilder: (_, index) {
                    return _buildLayout(context, index);
                  });



                 //counting is number of **blueplus** icon is clicked
     Widget  _buildLayout(BuildContext context, int i) {       
      return Column(
      children: <Widget>[
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: <Widget>[
            Text(
              addContainer,
              style: TextStyle(color: Colors.blueGrey),
            ),
            Container(
              width: 64.0,
              alignment: Alignment.center,
              child: IconButton(
                  onPressed: () => {i == 0 ? addRow(i) : deleteRow(i)},
                  icon: Icon(
                    i == 0
                        ? Icons.add_circle_outline
                        : Icons.remove_circle_outline,
                    color: i == 0 ? Theme.of(context).primaryColor : Colors.red,
                  )),
            ),
          ],
        ),        
        _buildCheckBoxes()
      ],
    );
  }



Widget _buildCheckBoxes() {
    return
        Container(         
            width: MediaQuery.of(context).size.width,
            child: Column(
                mainAxisAlignment: MainAxisAlignment.start,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  InkWell(
                      onTap: () {
                        showHide();
                      },
                      child: Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: <Widget>[
                            Text(
                              productionmareketway,
                              style: TextStyle(
                                  fontSize: 18, fontWeight: FontWeight.bold),
                            ),
                            showHidee
                                ? Icon(Icons.keyboard_arrow_up)
                                : Icon(Icons.keyboard_arrow_down)
                          ])),
                  SizedBox(
                    width: 20,
                  ),
                  showHidee
                      ? ListView.builder(
                          shrinkWrap: true,
                          physics: const NeverScrollableScrollPhysics(),
                          itemCount: widget.responseMarket.length,
                          itemBuilder: (ctx, i) {
                            return _buildSingleCheckBox(
                                context,
                                widget.responseMarket[i].name,
                                widget.responseMarket[i].isChecked,
                                widget.responseMarket[i].id,
                                widget.responseMarket[i].identifier,
                                i);
                          })
                      : Container()
                ])
           );
          } 
  



Widget _buildSingleCheckBox(BuildContext context, String name, bool isChecked,
      int i, String identifier, int j) {
    return Container(
      child: new CheckboxListTile(
        title: new Text(name),
        value: isChecked,
        activeColor: Theme.of(context).primaryColor,
        checkColor: Colors.white,
        onChanged: (bool value) {
          setState(() {
            widget.responseMarket[i].isChecked = value;
            print(value);
            print(i);

            widget._onChecked(
                value,
                widget.responseMarket[i].id,
                widget.responseMarket[i].name,
                widget.responseMarket[i].identifier,
                counting);
          });
        
        },
      ),
    );
  }

添加和删除小部件功能

addRow(int i) {
setState(() {
  counting = counting + 1;
});
} 

 deleteRow(int i) {
    setState(() {
      counting = counting - 1;
    });
  }

我的回调函数

 onMarketChecked(var value, int i, String name, String identifier, int j) {
setState(() {
  if (responseMarket[i].isChecked == true) {
    nonMarketRepated.add(name);
  } else {
    nonMarketRepated.remove(responseMarket[i].name);
  }
});
}

【问题讨论】:

    标签: flutter listview arraylist checkbox


    【解决方案1】:

    这个问题是因为您通过countingwidget.responseMarket 控制所有副本。如果您希望所有副本单独工作,您需要实际复制它。

    我建议创建一个新的 StatefulWidget 来替换 _buildSingleCheckBox() & _buildCheckBoxes() 函数。我还在里面放了showHidee

    class CheckBoxesWidget extends StatefulWidget {
      final responseMarket;
    
      CheckBoxesWidget({this.responseMarket, Key key}) : super(key: key);
    
      @override
      _CheckBoxesWidgetState createState() => _CheckBoxesWidgetState();
    }
    
    class _CheckBoxesWidgetState extends State<CheckBoxesWidget> {
      bool showHidee;
    
      @override
      void initState() {
        showHidee = true;
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return Container(
          width: MediaQuery.of(context).size.width,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              InkWell(
                onTap: () {
                  showHide();
                },
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: <Widget>[
                    Text(
                      'productionmareketway',
                      style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
                    ),
                    showHidee
                        ? Icon(Icons.keyboard_arrow_up)
                        : Icon(Icons.keyboard_arrow_down)
                  ],
                ),
              ),
              SizedBox(
                width: 20,
              ),
              if (showHidee)
                Column(
                  children: widget.responseMarket
                      .map(
                        (e) => CheckboxListTile(
                          title: Text(e.name),
                          value: e.isChecked,
                          activeColor: Theme.of(context).primaryColor,
                          checkColor: Colors.white,
                          onChanged: (bool value) {
                            setState(() {
                              e.isChecked = value;
                            });
                          },
                        ),
                      )
                      .toList(),
                ),
            ],
          ),
        );
      }
    
      void showHide() {
        setState(() {
          showHidee = !showHidee;
        });
      }
    }
    

    其次,除了counting对replica的控制之外,你应该使用一个List来存储responseMarket在原始类中的所有replica。

    List<List<Market>> responseMarkets;
    
    @override
    void initState() {
      responseMarkets = [widget.responseMarket];
      super.initState();
    }
    
    ...
    @override
    Widget build(BuildContext context) {
      return ListView.builder(
          itemCount: responseMarkets.length,
          itemBuilder: (_, index) {
            return _buildLayout(context, index);
          });
    }
    
    ...
    Widget _buildLayout(BuildContext context, int i) {
      ...
      // replace _buildCheckBoxes() with this line
      CheckBoxesWidget(responseMarket: responseMarkets[i],), 
      ...
    }
    

    最后,你要修改addRowdeleteRow函数。每次创建一个新的 ResponseMarkets 对象。

    addRow(int i) {
      setState(() {
        responseMarkets.add(responseMarkets[0]
            .map((e) => ResponseMarkets(
                  id: e.id,
                  name: e.name,
                  identifier: e.identifier,
                  isChecked: e.isChecked,
                ))
            .toList());
      });
    }
    
    deleteRow(int i) {
      setState(() {
        responseMarkets.removeAt(i);
      });
    }
    

    【讨论】:

    • 在没有选择容器索引0并且添加容器时选择了复选框项时,但在选择容器索引0并添加容器时添加的复容器索引项时,请添加新容器值与索引 0 容器中的值一样。
    • 我注意到我没有解决您的问题,因为原始副本由 countingwidget.responseMarket 控制(这是创建此对象的最终版本)。我修改它并更新代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-02
    • 2019-06-27
    • 2021-05-06
    • 1970-01-01
    • 1970-01-01
    • 2011-10-24
    • 2013-08-24
    相关资源
    最近更新 更多