Skip to content

Instantly share code, notes, and snippets.

@vemarav
Created May 2, 2022 12:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vemarav/c9ce4f9733fafc926751af84fbe2a1d3 to your computer and use it in GitHub Desktop.
Save vemarav/c9ce4f9733fafc926751af84fbe2a1d3 to your computer and use it in GitHub Desktop.
todo list app using stateful widget
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