tesseract
tesseract

Reputation: 150

How do i set a checkbox to select and deselect other checkboxes in flutter?

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

Answers (2)

Md. Yeasin Sheikh
Md. Yeasin Sheikh

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

ARASHz4
ARASHz4

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

Related Questions