-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a showcase of a sheet with TextField
- Loading branch information
Showing
7 changed files
with
553 additions
and
3 deletions.
There are no files selected for viewing
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
This file was deleted.
Oops, something went wrong.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
import 'package:cookbook/showcase/todo_list/models.dart'; | ||
import 'package:cookbook/showcase/todo_list/todo_editor.dart'; | ||
import 'package:flutter/material.dart'; | ||
|
||
void main() { | ||
runApp(const _TodoListExample()); | ||
} | ||
|
||
class _TodoListExample extends StatelessWidget { | ||
const _TodoListExample(); | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return const MaterialApp(home: _Home()); | ||
} | ||
} | ||
|
||
class _Home extends StatefulWidget { | ||
const _Home(); | ||
|
||
@override | ||
State<_Home> createState() => _HomeState(); | ||
} | ||
|
||
class _HomeState extends State<_Home> { | ||
late final TodoList _todoList; | ||
|
||
@override | ||
void initState() { | ||
super.initState(); | ||
_todoList = TodoList(); | ||
} | ||
|
||
@override | ||
void dispose() { | ||
_todoList.dispose(); | ||
super.dispose(); | ||
} | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return Scaffold( | ||
appBar: AppBar( | ||
title: const Text('Todo List'), | ||
), | ||
body: _TodoListView(todoList: _todoList), | ||
floatingActionButton: FloatingActionButton( | ||
onPressed: () => addTodo(), | ||
child: const Icon(Icons.add), | ||
), | ||
); | ||
} | ||
|
||
Future<void> addTodo() async { | ||
final todo = await showTodoEditor(context); | ||
if (todo != null) { | ||
_todoList.add(todo); | ||
} | ||
} | ||
} | ||
|
||
class _TodoListView extends StatelessWidget { | ||
const _TodoListView({ | ||
required this.todoList, | ||
}); | ||
|
||
final TodoList todoList; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return ListenableBuilder( | ||
listenable: todoList, | ||
builder: (context, _) { | ||
return ListView.separated( | ||
itemCount: todoList.length, | ||
itemBuilder: (context, index) { | ||
return _TodoListViewItem( | ||
todo: todoList[index], | ||
checkboxCallback: (value) => todoList.toggle(index), | ||
); | ||
}, | ||
separatorBuilder: (context, index) { | ||
return const Divider(indent: 24); | ||
}, | ||
); | ||
}, | ||
); | ||
} | ||
} | ||
|
||
class _TodoListViewItem extends StatelessWidget { | ||
const _TodoListViewItem({ | ||
Key? key, | ||
required this.todo, | ||
required this.checkboxCallback, | ||
}) : super(key: key); | ||
|
||
final Todo todo; | ||
final ValueChanged<bool?> checkboxCallback; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
final statuses = <Widget>[ | ||
if (todo.priority != Priority.none) | ||
_StatusChip( | ||
icon: Icons.flag, | ||
color: todo.priority.color, | ||
label: todo.priority.displayName, | ||
), | ||
]; | ||
|
||
final description = switch (todo.description) { | ||
null => null, | ||
final text => Text( | ||
text, | ||
maxLines: 2, | ||
overflow: TextOverflow.ellipsis, | ||
style: Theme.of(context) | ||
.textTheme | ||
.bodyLarge | ||
?.copyWith(color: Colors.black54), | ||
), | ||
}; | ||
|
||
final secondaryContent = [ | ||
if (description != null) ...[description, const SizedBox(height: 8)], | ||
if (statuses.isNotEmpty && !todo.isDone) Wrap(children: statuses), | ||
]; | ||
|
||
return CheckboxListTile( | ||
value: todo.isDone, | ||
controlAffinity: ListTileControlAffinity.leading, | ||
onChanged: checkboxCallback, | ||
title: Text(todo.title), | ||
isThreeLine: secondaryContent.isNotEmpty, | ||
subtitle: switch (secondaryContent.isNotEmpty) { | ||
true => Column( | ||
crossAxisAlignment: CrossAxisAlignment.start, | ||
children: secondaryContent, | ||
), | ||
false => null, | ||
}, | ||
); | ||
} | ||
} | ||
|
||
class _StatusChip extends StatelessWidget { | ||
const _StatusChip({ | ||
required this.icon, | ||
required this.color, | ||
required this.label, | ||
}); | ||
|
||
final IconData icon; | ||
final Color? color; | ||
final String label; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return Chip( | ||
avatar: Icon(icon, color: color), | ||
label: Text(label), | ||
padding: EdgeInsets.zero, | ||
labelPadding: const EdgeInsets.only(right: 12), | ||
visualDensity: const VisualDensity( | ||
vertical: -4, | ||
horizontal: -4, | ||
), | ||
); | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import 'package:flutter/material.dart'; | ||
|
||
// TODO: Add 'reminder' and 'due date' fields. | ||
class Todo { | ||
final String title; | ||
final String? description; | ||
final Priority priority; | ||
final bool isDone; | ||
|
||
const Todo({ | ||
required this.title, | ||
this.description, | ||
this.priority = Priority.none, | ||
this.isDone = false, | ||
}); | ||
} | ||
|
||
enum Priority { | ||
high(displayName: 'High Priority', color: Colors.red), | ||
medium(displayName: 'Medium Priority', color: Colors.orange), | ||
low(displayName: 'Low Priority', color: Colors.blue), | ||
none(displayName: 'No Priority'); | ||
|
||
const Priority({ | ||
required this.displayName, | ||
this.color, | ||
}); | ||
|
||
final String displayName; | ||
final Color? color; | ||
} | ||
|
||
class TodoList extends ChangeNotifier { | ||
final List<Todo> _todos = []; | ||
|
||
int get length => _todos.length; | ||
|
||
Todo operator [](int index) => _todos[index]; | ||
|
||
void add(Todo todo) { | ||
_todos.insert(0, todo); | ||
notifyListeners(); | ||
} | ||
|
||
void toggle(int index) { | ||
final todo = _todos[index]; | ||
_todos[index] = Todo( | ||
title: todo.title, | ||
description: todo.description, | ||
priority: todo.priority, | ||
isDone: !todo.isDone, | ||
); | ||
notifyListeners(); | ||
} | ||
} |
Oops, something went wrong.