今天我們來完善我們的Todo App
首先,我們先修改我們的model,打開todo\lib\models\todo_model.dart
並修改
import 'dart:convert';
class TodoModel {
TodoModel({
this.id,
required this.title,
required this.done,
required this.date,
});
final int? id;
final String title;
final bool done;
final String date;
TodoModel copyWith({
int? id,
String? title,
bool? done,
String? date,
}) =>
TodoModel(
id: id ?? this.id,
title: title ?? this.title,
done: done ?? this.done,
date: date ?? this.date,
);
factory TodoModel.fromJson(String str) => TodoModel.fromMap(json.decode(str));
String toJson() => json.encode(toMap());
factory TodoModel.fromMap(Map<String, dynamic> json) => TodoModel(
id: json["id"],
title: json["title"],
done: json["done"] == 1 ? true : false,
date: json["date"],
);
Map<String, dynamic> toMap() => {
"id": id,
"title": title,
"done": done,
"date": date,
};
}
我們先在todo\lib\services\db_services.dart
加入刪除和編輯資料庫的方法
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:todo/models/todo_model.dart';
class DbService {
static final DbService instance = DbService._init();
static Database? _db;
//o banco de dados sera iniciado na instancia da classe
DbService._init();
Future<Database> get db async {
if (_db != null) return _db!;
_db = await _useDatabase('notes.db');
return _db!;
}
Future<Database> _useDatabase(String filePath) async {
final dbPath = await getDatabasesPath();
return await openDatabase(
join(dbPath, 'todo.db'),
onCreate: (db, version) {
return db.execute('''
create table Todo (
id integer primary key autoincrement,
title text not null,
date text,
done integer not null
)
''');
},
version: 1,
);
}
Future<List<TodoModel>> getTodos() async {
final db = await instance.db;
final result = await db.rawQuery('SELECT * FROM Todo');
print(result);
return result.map((i) {
return TodoModel.fromMap(i);
}).toList();
}
Future addTodo(TodoModel todo) async {
final db = await instance.db;
final id = await db.rawInsert(
'INSERT INTO Todo (Title, Date, Done) VALUES (?,?,?)',
[todo.title, todo.date, todo.done]);
}
Future deleteTodo(TodoModel todo) async {
final db = await instance.db;
final _todo =
await db.delete("Todo", where: "id = ?", whereArgs: [todo.id]);
}
Future editTodo(TodoModel todo) async {
final db = await instance.db;
final data = todo.toMap();
final result =
await db.update('Todo', data, where: "id = ?", whereArgs: [todo.id]);
print(result);
}
//fechar conexao com o banco de dados, funcao nao usada nesse app
Future close() async {
final db = await instance.db;
db.close();
}
}
打開todo\lib\states\Itodo_state.dart
,加入delete和edit方法
import 'package:todo/models/todo_model.dart';
abstract class ITodoState {
Future<List<TodoModel>> getTodos();
void addTodo(TodoModel todo);
void deleteTodo(TodoModel todo);
void editTodo(TodoModel todo);
}
打開todo\lib\states\todo_state.dart
,實現我們delete和edit方法
@override
void deleteTodo(TodoModel todo) async {
// TODO: implement deleteTodo
try {
await _dbProvider.deleteTodo(todo);
getTodos();
} catch (e) {
throw Exception();
}
}
@override
void editTodo(TodoModel todo) async {
// TODO: implement editTodo
try {
await _dbProvider.editTodo(todo);
getTodos();
} catch (e) {
throw Exception();
}
}
}
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:todo/services/db_services.dart';
import 'package:todo/models/todo_model.dart';
import 'package:todo/states/Itodo_state.dart';
class TodoState extends StateNotifier<List<TodoModel>> implements ITodoState {
TodoState(this.ref)
: _dbProvider = ref.watch(dbProvider),
super([]);
final Ref ref;
final DbService _dbProvider;
@override
Future<List<TodoModel>> getTodos() async {
// TODO: implement getTodos
try {
await Future.delayed(const Duration(seconds: 1));
final todos = await _dbProvider.getTodos();
state = todos;
} catch (e) {
throw Exception();
}
return state;
}
@override
void addTodo(TodoModel todo) async {
// TODO: implement addTodo
try {
await _dbProvider.addTodo(todo);
getTodos();
} catch (e) {
throw Exception();
}
// state = [
// ...state,
// todo,
// ];
}
@override
void deleteTodo(TodoModel todo) async {
// TODO: implement deleteTodo
try {
await _dbProvider.deleteTodo(todo);
getTodos();
} catch (e) {
throw Exception();
}
}
@override
void editTodo(TodoModel todo) async {
// TODO: implement editTodo
try {
await _dbProvider.editTodo(todo);
getTodos();
} catch (e) {
throw Exception();
}
}
}
final dbProvider = Provider((ref) => DbService.instance);
final todosProvider = StateNotifierProvider<TodoState, List<TodoModel>>((ref) {
return TodoState(ref);
});
打開todo\lib\ui\widgets\todo_item_widget.dart
並修改
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:todo/models/todo_model.dart';
import 'package:todo/states/todo_state.dart';
class TodoItem extends ConsumerWidget {
final TodoModel todo;
const TodoItem({
Key? key,
required this.todo,
}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
return Container(
color: Colors.grey,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const FlutterLogo(),
Text(todo.title),
TextButton(onPressed: () {}, child: Text('Done')),
ElevatedButton(
onPressed: () {
ref.read(todosProvider.notifier).deleteTodo(todo);
},
child: Text('Delete')),
],
),
);
}
}
todo\lib\ui\widgets\todo_list_widget.dart
也做修改,順便解決初始化todo list沒出現的問題
import 'package:flutter/cupertino.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:todo/models/todo_model.dart';
import 'package:todo/states/todo_state.dart';
import 'package:todo/ui/widgets/todo_item_widget.dart';
class TodoList extends ConsumerStatefulWidget {
const TodoList({Key? key}) : super(key: key);
@override
_TodoListState createState() => _TodoListState();
}
class _TodoListState extends ConsumerState<TodoList> {
@override
void initState() {
super.initState();
final todos = ref.read(todosProvider.notifier).getTodos();
}
@override
Widget build(BuildContext context) {
final todos = ref.watch(todosProvider);
return Column(
children: todos
.map(
(e) => TodoItem(
todo: e,
),
)
.toList(),
);
}
}
現在我們能刪除我們的todo item了
Delete