在颤动中单击按钮时添加小部件时处理动态复选框列表 [英] Handle the list of dynamic checkboxes when the widget is added on button click in flutter

查看:21
本文介绍了在颤动中单击按钮时添加小部件时处理动态复选框列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When clicking the add button, the same widget is replicated. The widget contains the list of checkboxes that are multi selectable. I am able to replicate the widget but I got problem to handle the checkboxes according to the index of the widget. In image below the checkbox checked state is replicated along with the new add widget.

我已经实现如下:

根据addbutton点击构建widget

Build the widget according to the addbutton click

  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);
  }
});
}

推荐答案

这个问题是因为你通过 countingwidget.responseMarket 控制所有副本.如果你想让所有的副本单独工作,你需要实际复制它.

This issue is because you control all replica by counting and widget.responseMarket. If you want all replicas work individually, you need to Replica it actually.

我建议创建一个新的 StatefulWidget 来代替 _buildSingleCheckBox() &_buildCheckBoxes() 函数.我也把 showHidee 放在里面.

I suggest to create a new StatefulWidget to replace _buildSingleCheckBox() & _buildCheckBoxes() function. I also put showHidee inside it.

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存储在原类中.

Second, beyond control the replica by counting, you should use a List to store all replica of responseMarket in the original class.

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 对象.

Finally, you have to modify the addRow, deleteRow function. Each time create a new ResponseMarkets Object.

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);
  });
}

这篇关于在颤动中单击按钮时添加小部件时处理动态复选框列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆