Riverpod, Flutter - how to change Checkbox state by index

103 views Asked by At

There is a CartCheckbox widget (object) with the true state. It is added to the CartItemWidget from which the List is then formed. Since a List from a CartItemWidget with the same object is added to ListView.builder (as I understand it), when you click on a checkbox, all checkboxes in the list become inactive..

added a provider that could return Map key and value to me

final checkboxesProvider = StateProvider<Map<String, bool>>((ref) => {'Checkbox1': true});

then this..

class CartCheckbox extends ConsumerWidget {
  const CartCheckbox({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final checkboxes = ref.watch(checkboxesProvider);
  //  ref.watch(selectAllProvider);

    return Column(
      children: [
        ...checkboxes.entries.map((entry) {
          return Checkbox(
            value: entry.value,
            activeColor: AppColors.main,
            onChanged: (bool? value) {
              ref.watch(checkboxesProvider.notifier).state[entry.key] = value!;
              ref.refresh(selectAllProvider.notifier).state = ref.read(checkboxesProvider.notifier).state.values.every((v) => v);
            },
          );
        },
        ),
      ],
    );
  }
}

sheet is created here..

  child: ListView.builder(
                    itemCount: response.data.products.length,
                    itemBuilder: (context, index) {
                      return CartItemWidget(
                        key: ValueKey<String>(
                            response.data.products[index].price.price),
                        product: response.data.products[index],
                        cartState: state,
                      );
                    },
                  ),

the result was needed like this:

When we go to the cart, all checkboxes are active. After clicking on one of the checkboxes, this checkbox and “select all” will become inactive. When the last checkbox becomes active, "select all" also becomes active

how can you make each individual checkbox active or inactive (I think through index) based on this code)... maybe I’m wrong

Consumer selectAllButton() {
return Consumer(
  builder: (BuildContext context, WidgetRef ref, Widget? child) {
    final selectAll = ref.watch(selectAllProvider);

    return Align(
        alignment: Alignment.centerLeft,
        child: Padding(
          padding: const EdgeInsets.only(left: 16),
          child: GestureDetector(
            onTap: () {},
            child: Row(
              children: [
                Checkbox(
                  value: selectAll,
                  activeColor: AppColors.main,
                  onChanged: (bool? value) {
                    ref.read(selectAllProvider.notifier).state = value!;
                    ref.read(checkboxesProvider.notifier).state = ref
                        .read(checkboxesProvider.notifier)
                        .state
                        .map((key, value) => MapEntry(key, !selectAll));
                  },
                ),
                Insets.gapW8,
                const Text(
                  "Обрати всі",
                  style: TextStyle(
                      fontSize: 16,
                      fontWeight: FontWeight.w400,
                      color: AppColors.textGray80),
                ),
              ],
            ),
          ),
        ));
  },
);

}

Widget build(BuildContext context) {
super.build(context);
return Consumer(
  builder: (context, ref, child) {
    return Container(
      decoration: const BoxDecoration(
        color: Colors.white,
        border: Border(
          bottom: BorderSide(width: 1, color: AppColors.line),
        ),
      ),
      child: ProductPushWrapper(
        product: product,
        child: Padding(
                padding: const EdgeInsets.symmetric(
                    horizontal: 16, vertical: 16),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                       const CartCheckbox(),
                    Row(
                      children: [
                        avatarImage(),
                        Insets.gapW20,
                        Expanded(
                          child: Column(
                            crossAxisAlignment: Cross
1

There are 1 answers

4
Md. Yeasin Sheikh On

I am just using checkboxesProvider to control the selection including select all.

While Map override duplicate key's value, you can take this advantage on updating item.

ref
    .watch(checkboxesProvider.notifier)
    .update((state) => {...state, entry.key: value!});
class CartCheckbox extends ConsumerWidget {
  const CartCheckbox({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final checkboxes = ref.watch(checkboxesProvider);

    return Column(
      children: [
        CheckboxListTile(
          title: const Text('Check all'),
          value: checkboxes.values.every((element) => element),
          onChanged: (bool? value) {
            ref.watch(checkboxesProvider.notifier).update((state) {
              return state.map((key, _) => MapEntry(key, value ?? false));
            });
          },
        ),
        ...checkboxes.entries.map(
          (entry) {
            return CheckboxListTile(
              title: Text(entry.key),
              value: entry.value,
              onChanged: (bool? value) {
                ref.watch(checkboxesProvider.notifier).update((state) => {
                      ...state,
                      entry.key: value!,
                    });
              },
            );
          },
        ),
      ],
    );
  }
}