Created
May 2, 2022 12:33
-
-
Save vemarav/c9ce4f9733fafc926751af84fbe2a1d3 to your computer and use it in GitHub Desktop.
todo list app using stateful widget
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
const Color darkBlue = Color.fromARGB(255, 18, 32, 47); | |
// bloc & get packages | |
// behind | |
void main() { | |
runApp(MyApp()); | |
// expects to receive a widget and mount it as a root widget | |
} | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
// CuprtinoApp | |
theme: ThemeData( | |
primarySwatch: Colors.purple, | |
), | |
debugShowCheckedModeBanner: false, | |
// home: TodoList(), // '/', | |
routes: { | |
'/': (context) => TodoList() | |
}, | |
); | |
} | |
} | |
class Todo { | |
final int id; | |
final String text; | |
final bool isCompleted; | |
Todo({required this.id, required this.text, required this.isCompleted}); | |
Todo.initialize({String? text}) | |
: id = DateTime.now().microsecondsSinceEpoch, | |
text = text ?? '', | |
isCompleted = false; | |
Todo copyWith({int? id, String? text, bool? isCompleted}) { | |
return Todo( | |
id: id ?? this.id, | |
text: text ?? this.text, | |
isCompleted: isCompleted ?? this.isCompleted, | |
); | |
} | |
@override | |
String toString() { | |
return {'id': id, 'text': text, 'isCompleted': isCompleted}.toString(); | |
} | |
} | |
class TodoCard extends StatelessWidget { | |
final Todo todo; | |
final void Function(Todo todo)? deleteTodo, checkTodo; // (Todo todo) {} | |
const TodoCard({required this.todo, this.deleteTodo, this.checkTodo}); | |
@override | |
Widget build(BuildContext context) { | |
return Row( | |
children: [ | |
Checkbox( | |
onChanged: (bool? state) { | |
checkTodo!(todo); | |
}, | |
value: todo.isCompleted, | |
), // null disable checkbox | |
Expanded(child: Text(todo.text)), // flex: 1 | |
IconButton( | |
icon: const Icon(Icons.delete), | |
onPressed: () => deleteTodo!(todo), | |
), | |
], | |
); | |
} | |
} | |
class TodoList extends StatefulWidget { | |
// @immutable | |
final String name = 'Todos'; | |
@override | |
TodoListState createState() => TodoListState(); | |
} | |
class TodoListState extends State<TodoList> { | |
// 1. createState() // invoked only once | |
// 2. initState() // invoked only once | |
// 3. didChangeDependencies() | |
// 4. build() | |
// 5. didUpdateWidget() | |
// 6. dispose() // invoked only once, when widget is removed from the tree | |
// streams | |
final textController = TextEditingController(); | |
List<Todo> todos = []; | |
void addTodo() { | |
final text = textController.text; | |
if (text.isEmpty) return; | |
setState(() => todos.add(Todo.initialize(text: text))); // todo | |
textController.clear(); | |
} | |
void deleteTodo(Todo todo) { | |
setState(() => todos.remove(todo)); | |
} | |
void checkTodo(Todo todo) { | |
final index = todos.indexOf(todo); | |
setState(() => todos[index] = todo.copyWith(isCompleted: !todo.isCompleted)); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar(title: Text(widget.name)), | |
body: Column( | |
children: [ | |
Row( | |
children: [ | |
Expanded( | |
child: TextField( | |
controller: textController, | |
decoration: const InputDecoration( | |
contentPadding: EdgeInsets.all(16), | |
border: InputBorder.none, | |
), | |
), | |
), | |
TextButton( | |
child: const Text('Save'), | |
onPressed: addTodo, | |
), | |
], | |
), | |
const Divider(color: Colors.purple, height: 0), | |
Expanded( | |
child: ListView( | |
children: todos | |
.map((todo) => TodoCard(todo: todo, deleteTodo: deleteTodo, checkTodo: checkTodo)) | |
.toList(), | |
), | |
) | |
], | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment