如何在 Flutter 中使用 SharedPreferences 保存多个复选框的状态?

问题描述 投票:0回答:1

我正在学习 flutter,现在正在使用 sqflite 进行本地存储的待办事项列表项目。我在用于构建我的 SliverList 的卡片 (TestListItem) 的活动中实现了一个复选框,并希望在用户关闭和重新打开应用程序时保存它的状态。我尝试使用 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;
    });
  }

这是复选框:

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();
      });
    }),

这是提供者:

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();
  }
}

这是我的 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,
                              ),
                            ),
                          ),
                        ],
                      );
                    }
                  }

有了这个,我正在保存状态,但它对所有复选框应用相同的值(当我关闭并重新打开应用程序时,它们都被选中,反之亦然)。

我不知道我能做些什么来单独保存它们。我是否必须在提供程序中保存一个 bool 列表(代表选中的值),或者在 sqflite 数据库中创建一个列(再次代表选中的值)?

SharedPreferences 应该很简单吧?我该如何解决...

flutter checkbox sharedpreferences flutter-provider sqflite
1个回答
0
投票

非常感谢 Yeasin Sheikh 的帮助,我设法找到了正确的代码来实现我想要的。

解决方案基于您将 taskId 作为键传递给 SharedPreferences 的答案,而在函数 _savedCheckedValue() 中我忘记更新 _checkbox 值。

工作代码如下:

class TestListItem extends StatefulWidget {
  final TaskModel task;
  final int index;

  const TestListItem({
   Key? key,
   required this.task,
   required this.index,
  }) : super(key: key);

  @override
    State<TestListItem> createState() => _TestListItemState();
}

class _TestListItemState extends State<TestListItem> {
 bool _checkbox = false;

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

 _savedCheckedValue(bool isChecked) async {
   SharedPreferences prefs = await SharedPreferences.getInstance();
   setState(() {
   prefs.setBool(widget.task.taskId, isChecked);
   });
 }

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

在 CheckBoxListTile 的 onChanged 方法中:

  onChanged: (bool? value) {
           setState(() {
             _checkbox = !_checkbox;
             _savedCheckedValue(_checkbox);
           });
  }
    
© www.soinside.com 2019 - 2024. All rights reserved.