Handle the list of dynamic checkboxes when the widget is added on button click in flutter
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.
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;
});
}
}
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],),
...
}
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);
});
}
Comments
-
Nabin Dhakal over 1 year
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.
I have implemented as follows:
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); }); }, ), ); }
Add and delete widget function
addRow(int i) { setState(() { counting = counting + 1; }); } deleteRow(int i) { setState(() { counting = counting - 1; }); }
My callback function
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); } }); }
-
Nabin Dhakal over 3 yearsIt worked in case when no checkbox items is selected of the container index 0 and the container is added, but when selecting the checkboxlist items layout of container index 0 and adding containers the new container added will have the values as like in index 0 container.
-
yellowgray over 3 yearsI notice I didn't fix your issue becaue the original replica is control by
counting
andwidget.responseMarket
(which is final from this object created). I modify it and update the code.