Skip to content

Instantly share code, notes, and snippets.

@sgruhier
Created May 11, 2024 16:47
Show Gist options
  • Save sgruhier/06a50838b6b6d5154f0b2c25b8d44f36 to your computer and use it in GitHub Desktop.
Save sgruhier/06a50838b6b6d5154f0b2c25b8d44f36 to your computer and use it in GitHub Desktop.
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
void main() {
runApp(const ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Todo List with Riverpod',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const TodoListPage(),
);
}
}
class Todo {
String title;
bool completed;
Todo({
required this.title,
this.completed = false,
});
}
class TodoListNotifier extends StateNotifier<List<Todo>> {
TodoListNotifier() : super([]);
void addTodo(String title) {
state = [...state, Todo(title: title)];
}
void toggleCompleted(int index) {
var todo = state[index];
state = [
...state.sublist(0, index),
Todo(
title: todo.title,
completed: !todo.completed,
),
...state.sublist(index + 1),
];
}
void removeTodo(int index) {
state = [...state.sublist(0, index), ...state.sublist(index + 1)];
}
}
final todoListProvider = StateNotifierProvider<TodoListNotifier, List<Todo>>((ref) {
return TodoListNotifier();
});
class TodoListPage extends ConsumerWidget {
const TodoListPage({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
List<Todo> todos = ref.watch(todoListProvider);
return Scaffold(
appBar: AppBar(
title: const Text('Todo List'),
),
body: ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
final todo = todos[index];
return ListTile(
title: Text(todo.title),
leading: Checkbox(
value: todo.completed,
onChanged: (_) => ref.read(todoListProvider.notifier).toggleCompleted(index),
),
trailing: IconButton(
icon: const Icon(Icons.delete),
onPressed: () => ref.read(todoListProvider.notifier).removeTodo(index),
),
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () => _showAddTodoDialog(context, ref),
child: const Icon(Icons.add),
),
);
}
void _showAddTodoDialog(BuildContext context, WidgetRef ref) {
final TextEditingController controller = TextEditingController();
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('Add Todo'),
content: TextField(
controller: controller,
decoration: const InputDecoration(hintText: 'Todo title'),
),
actions: [
TextButton(
onPressed: () {
ref.read(todoListProvider.notifier).addTodo(controller.text);
Navigator.of(context).pop();
},
child: const Text('Add'),
),
],
);
},
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment