我正在开发一个待办事项应用程序,其中两个功能是将待办事项标记为已完成以及取消标记为已完成。它在按下时正常工作,并且
isDone
值也保存在共享首选项中,但是当我重新打开应用程序或更改屏幕时,它不会在 UI 上反映之前保存的 isDone
值。
这就是我的 todoWidget.dart 的样子:
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:todo/model/todo.dart';
import 'package:todo/provider/todoProvider.dart';
import 'package:todo/widgets/todoEditorWidget.dart';
class TodoWidget extends StatefulWidget {
final ToDo todo;
const TodoWidget({super.key, required this.todo});
@override
State<TodoWidget> createState() => _TodoWidgetState();
}
class _TodoWidgetState extends State<TodoWidget> {
Color _iconColor = Colors.white;
TextDecoration _todoTextDecoration = TextDecoration.none;
bool _editButtonVisibility = true;
void _markAsDone() async {
setState(() {
widget.todo.isDone = true;
_iconColor = Colors.green;
_todoTextDecoration = TextDecoration.lineThrough;
_editButtonVisibility = false;
});
final prefs = await SharedPreferences.getInstance();
final isDoneKey = 'isDone_${widget.todo.id}';
await prefs.setBool(isDoneKey, true);
}
void _unmarkAsDone() async {
setState(() {
widget.todo.isDone = false;
_iconColor = Colors.white;
_todoTextDecoration = TextDecoration.none;
_editButtonVisibility = true;
});
final prefs = await SharedPreferences.getInstance();
final isDoneKey = 'isDone_${widget.todo.id}';
await prefs.setBool(isDoneKey, false);
}
@override
Widget build(BuildContext context) {
return Card(
color: widget.todo.backgroundColor,
margin: const EdgeInsets.symmetric(vertical: 10, horizontal: 6),
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 10, 0, 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Row(
children: [
Text(
widget.todo.todoTime!,
style: const TextStyle(
fontSize: 18.0,
),
),
const SizedBox(width: 20,),
Expanded(
child: Text(
widget.todo.todoTask!,
softWrap: true,
style: TextStyle(
fontSize: 18.0,
decoration: _todoTextDecoration,
),
),
),
],
),
),
Row(
children: [
IconButton(
onPressed: () => widget.todo.isDone ? _unmarkAsDone() : _markAsDone(),
icon: Icon(Icons.done, color: _iconColor,),
padding: const EdgeInsets.all(5.0),
constraints: const BoxConstraints(),
tooltip: 'mark as done',
),
Visibility(
visible: _editButtonVisibility,
child: IconButton(
onPressed: () => _editTodo(widget.todo),
icon: const Icon(CupertinoIcons.pencil),
padding: const EdgeInsets.all(5.0),
constraints: const BoxConstraints(),
tooltip: 'edit task',),
),
IconButton(
onPressed: _deleteTodo,
icon: const Icon(CupertinoIcons.trash),
padding: const EdgeInsets.all(5.0),
constraints: const BoxConstraints(),
tooltip: 'delete task',),
],
),
],
),
),
);
}
}
并加载值,从
LoadTodos
类调用 TodoProvider
方法:
Future<void> loadTodos() async {
final prefs = await SharedPreferences.getInstance();
final savedTodos = prefs.getStringList('todos');
if (savedTodos != null) {
todosList = savedTodos.map((jsonString) {
final todo = ToDo.fromJson(jsonDecode(jsonString));
final isDoneKey = 'isDone_${todo.id}';
todo.isDone = prefs.getBool(isDoneKey) ?? false; // Load the isDone status
return todo;
}).toList();
}
}
在主页上构建待办事项
ListView
时调用。这就是我的 FutureBuilder
的样子:
FutureBuilder<void>(
future: Provider.of<ToDoProvider>(context).loadTodos(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Consumer<ToDoProvider>(
builder: (context, todoProvider, child) {
final todosForSelectedDate = todoProvider.getTodosForDate(selectedDate);
// Sort the todos list by time in ascending order
todosForSelectedDate.sort((a, b) {
final timeA = DateTime.parse('2023-10-08 ${a.todoTime}:00');
final timeB = DateTime.parse('2023-10-08 ${b.todoTime}:00');
return timeA.compareTo(timeB);
});
if (todosForSelectedDate.isEmpty) {
return Column(
children: [
const SizedBox(height: 30,),
Center(
child: Text("No todos today", style: Theme.of(context).textTheme.headlineLarge?.copyWith(fontSize: 25),),
),
],
);
} else {
return Expanded(
child: ListView.builder(
itemCount: todosForSelectedDate.length,
itemBuilder: (context, index) {
return TodoWidget(todo: todosForSelectedDate[index]);
},
physics: const BouncingScrollPhysics(),
),
);
}
},
);
} else if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
} else {
return const Center(child: Text('Error loading todos'));
}
},
),
每当我重新打开应用程序或更改日期,然后返回到同一个应用程序时,标记为“完成”的待办事项就会被取消标记。我错过了什么?