Flutter Riverpod 深入使用案例:构建待办事项应用
以下是一个使用 flutter_riverpod 的深入案例:
假设我们正在构建一个简单的待办事项应用程序。我们需要能够添加、编辑、删除和标记待办事项为已完成。我们将使用 flutter_riverpod 来管理应用程序的状态。
首先,我们需要创建一个待办事项类。它将包含待办事项的标题、描述和完成状态:
class Todo {
String title;
String description;
bool isCompleted;
Todo({
required this.title,
required this.description,
this.isCompleted = false,
});
}
接下来,我们需要创建一个提供者来管理待办事项的状态。我们将使用 StateNotifierProvider 提供者,它将使用 StateNotifier 来管理状态:
final todosProvider = StateNotifierProvider<TodosNotifier, List<Todo>>((ref) {
return TodosNotifier();
});
class TodosNotifier extends StateNotifier<List<Todo>> {
TodosNotifier() : super([]);
void addTodo(Todo todo) {
state = [...state, todo];
}
void editTodo(int index, Todo todo) {
state = [
...state.sublist(0, index),
todo,
...state.sublist(index + 1),
];
}
void deleteTodo(int index) {
state = [
...state.sublist(0, index),
...state.sublist(index + 1),
];
}
void toggleTodoCompletion(int index) {
final todo = state[index];
state = [
...state.sublist(0, index),
todo.copyWith(isCompleted: !todo.isCompleted),
...state.sublist(index + 1),
];
}
}
接下来,我们可以在我们的应用程序中使用提供者。在这个示例中,我们将创建一个简单的页面来显示待办事项列表,并提供添加、编辑和删除待办事项的功能。我们还将为每个待办事项提供一个复选框,以标记待办事项是否已完成:
class TodosPage extends ConsumerWidget {
@override
Widget build(BuildContext context, ScopedReader watch) {
final todos = watch(todosProvider);
return Scaffold(
appBar: AppBar(
title: const Text('Todos'),
),
body: ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
final todo = todos[index];
return ListTile(
leading: Checkbox(
value: todo.isCompleted,
onChanged: (_) {
context.read(todosProvider.notifier).toggleTodoCompletion(index);
},
),
title: Text(todo.title),
subtitle: Text(todo.description),
trailing: IconButton(
icon: const Icon(Icons.delete),
onPressed: () {
context.read(todosProvider.notifier).deleteTodo(index);
},
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => TodoEditorPage(
todo: todo,
onSave: (editedTodo) {
context.read(todosProvider.notifier).editTodo(index, editedTodo);
Navigator.pop(context);
},
),
),
);
},
);
},
),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => TodoEditorPage(
onSave: (newTodo) {
context.read(todosProvider.notifier).addTodo(newTodo);
Navigator.pop(context);
},
),
),
);
},
),
);
}
}
class TodoEditorPage extends StatefulWidget {
final Todo? todo;
final Function(Todo) onSave;
const TodoEditorPage({
Key? key,
this.todo,
required this.onSave,
}) : super(key: key);
@override
_TodoEditorPageState createState() => _TodoEditorPageState();
}
class _TodoEditorPageState extends State<TodoEditorPage> {
late TextEditingController _titleController;
late TextEditingController _descriptionController;
@override
void initState() {
super.initState();
_titleController = TextEditingController(text: widget.todo?.title ?? '');
_descriptionController = TextEditingController(text: widget.todo?.description ?? '');
}
@override
void dispose() {
_titleController.dispose();
_descriptionController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.todo != null ? 'Edit Todo' : 'Add Todo'),
),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
TextField(
controller: _titleController,
decoration: const InputDecoration(labelText: 'Title'),
),
const SizedBox(height: 16),
TextField(
controller: _descriptionController,
decoration: const InputDecoration(labelText: 'Description'),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
final newTodo = Todo(
title: _titleController.text,
description: _descriptionController.text,
);
widget.onSave(newTodo);
},
child: Text(widget.todo != null ? 'Save' : 'Add'),
),
],
),
),
);
}
}
最后,我们可以在我们的 main.dart 文件中使用 ProviderScope 来包装我们的根小部件,以确保提供者可以在整个应用程序中使用:
void main() {
runApp(
ProviderScope(
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Todo App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: TodosPage(),
);
}
}
这是一个简单的使用 flutter_riverpod 深入案例,展示了如何使用 StateNotifierProvider 和 ConsumerWidget 来管理和消费状态。通过这个案例,我们可以看到如何使用 flutter_riverpod 来构建复杂的应用程序。
原文地址: https://www.cveoy.top/t/topic/pgAe 著作权归作者所有。请勿转载和采集!