0

When I call the toggleSingleCardSelection, the isSelected of the chosen index will update but in my view, it will not fetch its updated data. Please help if I'm doing it the wrong way. I am also using the Get package. Using a stateful widget may solve my problem but I am learning the get package so I hope someone can guide me for my problem.

import 'package:flutter/material.dart';
import 'package:get/get.dart';

class Category {
  Category({
    required this.title,
    required this.isSelected,
  });
  String? title;
  bool? isSelected;
}

class MyController extends GetxController {
  final discomfortData = [
    Category(title: 'Ear', isSelected: false),
    Category(title: 'Heart', isSelected: false),
    Category(title: 'Kidney', isSelected: false),
    Category(title: 'Liver', isSelected: false),
    Category(title: 'Lungs', isSelected: false),
    Category(title: 'Skin', isSelected: false),
    Category(title: 'Stomach', isSelected: false),
    Category(title: 'Throat', isSelected: false),
  ].obs;

  void toggleSingleCardSelection(int index) {
    for (var indexBtn = 0; indexBtn < discomfortData.length; indexBtn++) {
      if (indexBtn == index) {
        discomfortData[index].isSelected = true;
        print('${dummyData[indexBtn].title} value: ${dummyData[index].isSelected}');
      } else {
        discomfortData[index].isSelected = false;
        print('${dummyData[indexBtn].title} value: ${dummyData[index].isSelected}');
      }
    }
  }
}

class MyView extends StatelessWidget {
  final MyController controller = Get.put(MyController());
  @override
  Widget build(BuildContext context) {
    return Obx(
      () => Scaffold(
        body: ListView.builder(
          itemCount: controller.discomfortData.length,
          itemBuilder: (ctx, index) {
            return Card(
              color: controller.discomfortData[index].isSelected!
                  ? Colors.blue
                  : Colors.white,
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(10),
              ),
              elevation: 5,
              child: InkWell(
                onTap: () => controller.toggleSingleCardSelection(index),
                child: SizedBox(
                  height: 120,
                  width: 120,
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Text(controller.discomfortData[index].title!),
                    ],
                  ),
                ),
              ),
            );
          },
        ),
      ),
    );
  }
}

This is the log when I click the 3rd index of the card:

enter image description here

RAlined
  • 13
  • 4

2 Answers2

0

After how many attempts I can say that reading the package's documentation is very helpful. Here's how I solved it. I guest having isSelected constructor is useless in my case.

class Category {
  Category({
    required this.title,
  });
  String? title;
}

class MyController extends GetxController {
  RxList<Category> dummyData = RxList<Category>([
    Category(title: 'Ear'),
    Category(title: 'Heart'),
    Category(title: 'Kidney'),
    Category(title: 'Liver'),
    Category(title: 'Lungs'),
    Category(title: 'Skin'),
    Category(title: 'Stomach'),
    Category(title: 'Throat'),
  ]);

  RxInt selectedIndex = 0.obs;

  void toggleSingleCardSelection(int index) {
    for (var indexBtn = 0; indexBtn < dummyData.length; indexBtn++) {
      if (indexBtn == index) {
        selectedIndex.value = index;
      } else {}
    }
  }
}

class MyView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final MyController controller = Get.put(MyController());
    return Scaffold(
      body: ListView.builder(
        itemCount: controller.dummyData.length,
        itemBuilder: (ctx, index) {
          return Obx(
            () => Card(
              color: controller.selectedIndex.value == index
                  ? Colors.blue
                  : Colors.amberAccent,
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(10),
              ),
              elevation: 5,
              child: InkWell(
                onTap: () => controller.toggleSingleCardSelection(index),
                child: SizedBox(
                  height: 120,
                  width: 120,
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Text(controller.dummyData[index].title!),
                    ],
                  ),
                ),
              ),
            ),
          );
        },
      ),
    );
  }
}
RAlined
  • 13
  • 4
0

By debugging your code I found 2 issues. First, the problem is in the for loop you are using to change values. As soon as the loop ends all the values are false again. I couldn't find why it is happening so I changed it.

    void toggleSingleCardSelection(int index) {
      discomfortData.where((element) => element.isSelected = false).toList();
      discomfortData[index].isSelected = true;
      discomfortData.forEach((element) {
        print('${element.title} value: ${element.isSelected}');
      });
      discomfortData.refresh();
    }

And secondly, Obx was not rebuilding because you are not updating the list but the variable of its member. so you have to call

discomfortData.refresh();

so listeners know that list has been updated.

TheFawad
  • 11
  • 2