import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
// 数据模型
class Todo {
final String id;
final String title;
final bool completed;
Todo({required this.id, required this.title, this.completed = false});
Todo copyWith({String? id, String? title, bool? completed}) {
return Todo(
id: id ?? this.id,
title: title ?? this.title,
completed: completed ?? this.completed,
);
}
}
// 模拟任务列表数据
class TodoListNotifier extends Notifier<List<Todo>> {
@override
List<Todo> build() => [
Todo(id: '1', title: '学习鸿蒙开发', completed: true),
Todo(id: '2', title: '掌握 Riverpod 2.0'),
Todo(id: '3', title: '部署项目到华为手机'),
];
void add(String title) {
state = [...state, Todo(id: DateTime.now().toString(), title: title)];
}
void toggle(String id) {
state = [
for (final todo in state)
if (todo.id == id) todo.copyWith(completed: !todo.completed)
else todo,
];
}
void delete(String id) {
state = state.where((todo) => todo.id != id).toList();
}
}
final todoListProvider = NotifierProvider<TodoListNotifier, List<Todo>>(TodoListNotifier.new);
// 过滤状态 Provider
enum TodoFilter { all, active, completed }
final todoFilterProvider = StateProvider<TodoFilter>((ref) => TodoFilter.all);
// 计算属性 Provider:基于过滤器处理后的列表
final filteredTodosProvider = Provider<List<Todo>>((ref) {
final todos = ref.watch(todoListProvider);
final filter = ref.watch(todoFilterProvider);
switch (filter) {
case TodoFilter.all:
return todos;
case TodoFilter.completed:
return todos.where((todo) => todo.completed).toList();
case TodoFilter.active:
return todos.where((todo) => !todo.completed).toList();
}
});
class RiverpodTodoPage extends ConsumerWidget {
const RiverpodTodoPage({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final todos = ref.watch(filteredTodosProvider);
final filter = ref.watch(todoFilterProvider);
return Scaffold(
appBar: AppBar(title: const Text('综合实战:任务管家')),
body: Column(
children: [
_buildFilterBar(ref, filter),
Expanded(
child: ListView.separated(
itemCount: todos.length,
separatorBuilder: (_, __) => const Divider(height: 1),
itemBuilder: (context, index) {
final todo = todos[index];
return ListTile(
leading: Checkbox(
value: todo.completed,
onChanged: (_) => ref.read(todoListProvider.notifier).toggle(todo.id),
),
title: Text(
todo.title,
style: TextStyle(
decoration: todo.completed ? TextDecoration.lineThrough : null,
color: todo.completed ? Colors.grey : Colors.black,
),
),
trailing: IconButton(
icon: const Icon(Icons.delete_sweep, color: Colors.orange),
onPressed: () => ref.read(todoListProvider.notifier).delete(todo.id),
),
);
},
),
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () => _showAddDialog(context, ref),
child: const Icon(Icons.add_task),
),
);
}
Widget _buildFilterBar(WidgetRef ref, TodoFilter currentFilter) {
return Container(
padding: const EdgeInsets.symmetric(vertical: 8),
color: Colors.grey.withOpacity(0.1),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: TodoFilter.values.map((filter) {
final isSelected = filter == currentFilter;
return ChoiceChip(
label: Text(_filterLabel(filter)),
selected: isSelected,
onSelected: (_) => ref.read(todoFilterProvider.notifier).state = filter,
);
}).toList(),
),
);
}
String _filterLabel(TodoFilter filter) {
return switch (filter) {
TodoFilter.all => '全部',
TodoFilter.active => '待办',
TodoFilter.completed => '已完成',
};
}
void _showAddDialog(BuildContext context, WidgetRef ref) {
final controller = TextEditingController();
showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('添加新回复'),
content: TextField(
controller: controller,
autofocus: true,
decoration: const InputDecoration(hintText: '写点什么...'),
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('取消'),
),
ElevatedButton(
onPressed: () {
if (controller.text.isNotEmpty) {
ref.read(todoListProvider.notifier).add(controller.text);
}
Navigator.pop(context);
},
child: const Text('保存'),
),
],
),
);
}
}