vendredi 5 mai 2023

How to save the State of multiple checkbox with SharedPreferences in Flutter?

I'm learning flutter and right now working on a To Do List project with local storage using sqflite. I implemented a checkbox in the activities from the card (TestListItem) that I used to build my SliverList and want to save it state for when the user close and reopen the app. I tried to use the SharedPreferences:

class _TestListItemState extends State<TestListItem> {
  bool _checkbox = false;
  final TextEditingController updatedTaskController = 
  TextEditingController();
  final TextEditingController updatedDateController = 
  TextEditingController();

  @override
  void initState() {
  _loadCheckedValue();
  }

  _savedCheckedValue() async {
    SharedPreferences prefs = await 
    SharedPreferences.getInstance();
    setState(() {
      prefs.setBool("check", _checkbox);
    });
  }

  _loadCheckedValue() async {
    SharedPreferences prefs = await 
    SharedPreferences.getInstance();
    bool? isChecked = prefs.getBool("check");
    setState(() {
      _checkbox = isChecked ?? false;
    });
  }

Here's the checkbox:

child: CheckboxListTile(
    controlAffinity: ListTileControlAffinity.leading,
    secondary: IntrinsicWidth(
      child: Row(...),
    )
    title: Text(...),
    ),
    subtitle: Text(...),
    ),
    activeColor: fabColor,
    value: _checkbox,
    onChanged: (bool? value) async {
      setState(() {
        _checkbox = !_checkbox;
        _savedCheckedValue();
      });
    }),

Here's the Provider:

class TaskProvider extends ChangeNotifier {
  List<TaskModel> tasks = [];
  List<bool> checked = [];

  Future insertInDatabase(String activity, String date) async {
    final newTask =
      TaskModel(taskId: const Uuid().v1(), activity: activity, 
      date: date);
    tasks.add(newTask);
    await TaskDao().save(TaskModel(
        taskId: newTask.taskId,
        activity: newTask.activity,
        date: newTask.date));
    notifyListeners();
  }

  Future<List<TaskModel>> readFromDatabase() async {
    final taskList = await TaskDao().findAll();
    tasks = taskList;
    return tasks;
  }

  Future updateFromDatabase(
    String taskId,
    String activity,
    String date,
  ) async {
    final updatedTask =
    TaskModel(taskId: taskId, activity: activity, date: date);
    await TaskDao().update(updatedTask);
    notifyListeners();
  }

  Future deleteFromDatabase(String taskId) async {
    await TaskDao().delete(taskId);
    notifyListeners();
  }
}

And here's my SliverList:

child: Consumer<TaskProvider>(
      builder: (BuildContext context, TaskProvider provider, 
      Widget? child)
        {return FutureBuilder<List<TaskModel>>(
          future: provider.readFromDatabase(),
          builder: (context, snapshot) {
            var items = snapshot.data;
            switch (snapshot.connectionState) {
              case ConnectionState.none:
                {
                  return const Loading();
                }
              case ConnectionState.waiting:
                {
                  return const Loading();
                }
              case ConnectionState.active:
                {
                  return const Loading();
                }
              case ConnectionState.done:
                {
                  if (snapshot.hasData && items != null) {
                    if (items.isNotEmpty) {
                      return CustomScrollView(
                        slivers: <Widget>[
                          SliverToBoxAdapter(
                            child: Text(...),
                          ),
                          SliverPadding(...),
                            sliver: SliverList(
                              delegate: SliverChildBuilderDelegate(
                                    (context, index) {
                                  return TestListItem(
                                    task: items[index], index: 
                                    index,);
                                },
                                childCount: items.length,
                              ),
                            ),
                          ),
                        ],
                      );
                    }
                  }

With this I'm saving the state, but it applys the same value to all checkboxes (when I check one close and reopen the app they are all checked, same with the opposite).

I'm not getting what can I do to save them individually. Do I have to save a list of bool (representing the checked values) in provider, or create a column in the sqflite database (again representing the checked values)?

It should be simple with the SharedPreferences right? How can I solve this...




Aucun commentaire:

Enregistrer un commentaire