install
dependencies:
...
moor_flutter:
dev_dependencies:
...
moor_generator:
build_runner:
lib\db\moor.db.dart
import 'package:moor_flutter/moor_flutter.dart';
part 'moor.db.g.dart';
// 建表
class Tasks extends Table {
IntColumn get id => integer().autoIncrement()();
TextColumn get name => text().withLength(min: 1, max: 50)();
DateTimeColumn get dueData => dateTime().nullable()();
BoolColumn get completed => boolean().withDefault(const Constant(false))();
}
@UseMoor(tables: [Tasks])
class AppDatabase extends _$AppDatabase {
AppDatabase()
: super(FlutterQueryExecutor.inDatabaseFolder(path: 'db.sqlite'));
@override
int get schemaVersion => 1;
Future<List<Task>> get getAllTasks => select(tasks).get();
/// 每当基础数据发生变化时,都会发出新项
Stream<List<Task>> watchAllTasks() => select(tasks).watch();
/// 插入一条数据
Future<int> insertTask({
String name,
DateTime dueData,
}) =>
into(tasks).insert(
TasksCompanion(
name: Value(name),
dueData: Value(dueData),
),
);
/// 更新一条数据
Future<bool> updateTask(Task task) => update(tasks).replace(task);
/// 删除一条数据
Future<int> deleteTask(Task task) => delete(tasks).delete(task);
}
lib\store\main\main.store.dart
import 'package:flutter_moor_demo/db/moor.db.dart';
class MainStore {
final dbService = DBService();
}
class DBService {
final database = AppDatabase();
Stream<List<Task>> get tasks$ =>
database.watchAllTasks().map((List<Task> tasks) {
/// 排序,把完成的排在后面
tasks.sort(
(a, b) => _getInt(a.completed).compareTo(_getInt(b.completed)),
);
return tasks;
});
int _getInt(bool b) {
return b ? 1 : 0;
}
}
final MainStore mainStore = MainStore();
lib\main.dart
import 'package:flutter/material.dart';
import 'package:flutter_moor_demo/store/main/main.store.dart';
import 'db/moor.db.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
DateTime newTaskDate;
TextEditingController controller;
@override
void initState() {
super.initState();
controller = TextEditingController();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Tasks'),
),
body: Column(
children: <Widget>[
Expanded(
child: StreamBuilder<List<Task>>(
stream: mainStore.dbService.tasks$,
initialData: List<Task>(),
builder: (context, snap) {
if (snap.connectionState == ConnectionState.active) {
List<Task> tasks = snap.data;
if (tasks.isEmpty) return Center(child: Text('Not Data'));
return ListView.builder(
itemCount: tasks.length + 1,
itemBuilder: (context, int index) {
if (index == 0) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Center(child: Text('taskS #${tasks.length}')),
);
}
final task = tasks[index - 1];
return Dismissible(
key: ValueKey(task.id),
background: Container(color: Colors.red),
onDismissed: (DismissDirection d) {
mainStore.dbService.database.deleteTask(task);
},
child: CheckboxListTile(
title: Text(task.name),
subtitle: Text(task.dueData?.toString() ?? 'No date'),
value: task.completed,
onChanged: (bool nv) {
mainStore.dbService.database
.updateTask(task.copyWith(completed: nv));
},
),
);
},
);
} else if (snap.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else {
return SizedBox();
}
},
),
),
ListTile(
title: TextField(
controller: controller,
decoration: InputDecoration(hintText: 'Task Name'),
onSubmitted: (String v) {
mainStore.dbService.database.insertTask(
name: v.trim(),
dueData: newTaskDate,
);
_reset();
},
),
trailing: IconButton(
icon: Icon(Icons.calendar_today),
onPressed: () async {
DateTime now = DateTime.now();
Duration d = Duration(days: 10);
newTaskDate = await showDatePicker(
context: context,
initialDate: now,
firstDate: now.subtract(d),
lastDate: now.add(d));
},
),
)
],
),
);
}
void _reset() {
setState(() {
controller.clear();
newTaskDate = null;
});
}
}

所有评论(0)