在颤动中单击按钮时添加小部件时处理动态复选框列表
Posted
技术标签:
【中文标题】在颤动中单击按钮时添加小部件时处理动态复选框列表【英文标题】: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);
);
【问题讨论】:
【参考方案1】:这个问题是因为您通过counting
和widget.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],),
...
最后,你要修改addRow
,deleteRow
函数。每次创建一个新的 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 容器中的值一样。 我注意到我没有解决您的问题,因为原始副本由counting
和 widget.responseMarket
控制(这是创建此对象的最终版本)。我修改它并更新代码。以上是关于在颤动中单击按钮时添加小部件时处理动态复选框列表的主要内容,如果未能解决你的问题,请参考以下文章