在颤动中单击按钮时添加小部件时处理动态复选框列表 [英] Handle the list of dynamic checkboxes when the widget is added on button click in flutter
问题描述
单击添加按钮时,将复制相同的小部件.该小部件包含可多选的复选框列表.我能够复制小部件,但我在根据小部件的索引处理复选框时遇到问题.在下图中,复选框选中状态与新添加小部件一起复制.
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);
}
});
}
推荐答案
这个问题是因为你通过 counting
和 widget.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],),
...
}
最后还要修改addRow
、deleteRow
函数.每次创建一个新的 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屋!