Reputation: 150
I have a checkbox in a stateful widget :
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Transform.scale(
scale: 1.3,
child: Checkbox(
side: MaterialStateBorderSide.resolveWith(
(Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
return const BorderSide(
width: 2, color: Color(0xff34495E));
}
return const BorderSide(
width: 1, color: Color(0xffB0BEC1));
},
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5)),
activeColor: Color(0xff34495E),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
visualDensity: VisualDensity(horizontal: -4, vertical: -4),
value: value,
onChanged: (value) {
setState(() {
this.value = value;
});
},
),
),
SizedBox(
width: 10,
),
Text(
'Select all',
style: GoogleFonts.poppins(
color: Colors.black87,
fontSize: 12,
fontWeight: FontWeight.w400),
),
],
),
And have checkboxes in a DIFFERENT stateful widget ( in a list tile ) :
Visibility(
visible: controller.isCheboxVisible.value,
child: Transform.scale(
scale: 1.3,
child: Checkbox(
side: MaterialStateBorderSide.resolveWith(
(Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
return const BorderSide(
width: 2, color: Color(0xff34495E));
}
return const BorderSide(
width: 1, color: Color(0xffB0BEC1));
},
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5)),
activeColor: Color(0xff34495E),
//materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
//visualDensity: VisualDensity(horizontal: -4, vertical: -4),
value: isChecked,
onChanged: (value) {
setState(() {
this.isChecked = value;
});
},
),
),
)
How do i make the first checkbox to Select all & Un-select all checkboxes in the other stateful widget?
I have tried using a package on pub.dev but it didn't turn out good, i also don't like the fact that i have to use a third party package for the simplest of things.
Please i need guidance on this.
Thanks
Upvotes: 0
Views: 1554
Reputation: 63569
To selected and deselect all, we need to communicate the state between widget. callback method is helpful here.
class MyWr2 extends StatefulWidget {
const MyWr2({super.key});
@override
State<MyWr2> createState() => _MyWr2State();
}
class _MyWr2State extends State<MyWr2> {
List<String> items = ["A", "B", "C"];
List<String> selectedItem = [];
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
AllItemCheckHandler(
// im not using list equality
isAllSelected: items.length == selectedItem.length,
selectAll: (isAllSelected) {
if (isAllSelected) {
selectedItem = items.toList(); // not passing reference
} else {
selectedItem.clear();
}
setState(() {});
},
),
...items
.map((e) => CheckboxListTile(
value: selectedItem.contains(e),
onChanged: (value) {
if (selectedItem.contains(e)) {
selectedItem.remove(e);
} else {
selectedItem.add(e);
}
setState(() {});
},
title: Text(e),
))
.toList(),
],
),
);
}
}
class AllItemCheckHandler extends StatefulWidget {
const AllItemCheckHandler(
{super.key, required this.selectAll, this.isAllSelected = false});
final Function(bool) selectAll;
final bool isAllSelected;
@override
State<AllItemCheckHandler> createState() => _AllItemCheckHandlerState();
}
class _AllItemCheckHandlerState extends State<AllItemCheckHandler> {
@override
Widget build(BuildContext context) {
return CheckboxListTile(
value: widget.isAllSelected,
onChanged: (value) {
setState(() {});
widget.selectAll(value ?? false);
},
);
}
}
Upvotes: 1
Reputation: 311
You should create a controller in DIFFERENT stateful widget
class DifferentStatefulWidgetController {
updateCheckBox(bool value) {
_updateCheckBox?.call(value);
}
void Function(bool value)? _updateCheckBox;
}
class DifferentStatefulWidget extends StatefulWidget {
const DifferentStatefulWidget({Key? key, required this.controller}) : super(key: key);
final DifferentStatefulWidgetController controller;
@override
State<DifferentStatefulWidget> createState() => _DifferentStatefulWidgetState();
}
class _DifferentStatefulWidgetState extends State<DifferentStatefulWidget> {
bool isChecked = false;
@override
void initState() {
widget.controller._updateCheckBox = (value) {
setState(() {
isChecked = value!;
});
};
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Checkbox(
value: isChecked,
onChanged: (value) {
setState(() {
isChecked = value!;
});
},
),
),
);
}
}
You should pass the controller in your widget
and call this in first widget
final differentStatefulWidgetController = DifferentStatefulWidgetController();
DifferentStatefulWidget(controller: differentStatefulWidgetController);
differentStatefulWidgetController.updateCheckBox(true);
Upvotes: 1