Skip to content

Instantly share code, notes, and snippets.

@johnpryan
Last active November 19, 2019 18:47
Show Gist options
  • Save johnpryan/9e574ab997b3217fcef3f600d0c6954c to your computer and use it in GitHub Desktop.
Save johnpryan/9e574ab997b3217fcef3f600d0c6954c to your computer and use it in GitHub Desktop.
Todo App
import 'package:flutter_web/material.dart';
import 'package:flutter_web_test/flutter_web_test.dart';
import 'package:flutter_web_ui/ui.dart' as ui;
Future main() async {
await ui.webOnlyInitializePlatform();
runApp(TasksApp());
}
class Task {
bool done;
String description;
Task(this.done, this.description);
}
class TasksApp extends StatefulWidget {
@override
_TasksAppState createState() => _TasksAppState();
}
class _TasksAppState extends State<TasksApp> {
List<Task> tasks = [
Task(false, 'Feed the cat'),
Task(false, 'Cook breakfast'),
];
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: SafeArea(
child: Scrollbar(
child: ReorderableListView(
header: Header('My Tasks'),
onReorder: (oldIndex, newIndex) {
setState(() {
if (oldIndex < newIndex) {
// removing the item at oldIndex will shorten the list by 1.
newIndex -= 1;
}
final Task element = tasks.removeAt(oldIndex);
tasks.insert(newIndex, element);
});
},
children: [
...tasks.map(
(t) => Dismissible(
key: ValueKey(t),
child: TaskView(task: t),
onDismissed: (direction) {
setState(() {
tasks.remove(t);
});
},
background: Container(
color: Colors.blue,
),
),
),
],
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
tasks.insert(0, Task(false, ''));
});
},
child: Icon(Icons.add),
),
),
);
}
}
class TaskView extends StatefulWidget {
final Task task;
TaskView({
@required this.task,
}) : super(key: ValueKey(task));
@override
_TaskViewState createState() => _TaskViewState();
}
class _TaskViewState extends State<TaskView> {
static const textStyle = TextStyle(fontSize: 16, color: Colors.black);
TextEditingController textController;
FocusNode focusNode;
@override
void initState() {
super.initState();
textController = TextEditingController()
..text = widget.task.description
..addListener(() {
setState(() {
widget.task.description = textController.text;
});
});
focusNode = FocusNode();
}
@override
Widget build(BuildContext context) {
return Row(
children: [
Checkbox(
value: widget.task.done,
onChanged: (checked) {
setState(() {
widget.task.done = checked;
});
},
),
Expanded(
child: TextField(
controller: textController,
focusNode: focusNode,
style: textStyle,
cursorColor: Colors.blue,
decoration: InputDecoration(
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
),
),
),
Padding(
padding: const EdgeInsets.all(4.0),
child: Icon(
Icons.drag_handle,
color: Colors.grey,
),
)
],
);
}
}
class Header extends StatelessWidget {
final String title;
static const TextStyle headerStyle =
TextStyle(fontSize: 32, fontWeight: FontWeight.w600);
Header(this.title);
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.fromLTRB(12, 8, 12, 8),
child: Column(
children: [
Text(
title,
style: headerStyle,
),
],
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment