Flutter数据库编辑器插件drift_editors的使用
Flutter数据库编辑器插件drift_editors的使用
描述
这个包的出现是因为我发现我在编写用于编辑用drift
编写的行的用户界面时花费了大量时间。这不仅非常无聊,而且缺乏创造性,我觉得这些工作应该由更动态的东西来处理,这样我就可以继续添加各种编辑器的功能。
此外,即使我已经有了package:backstreets_widgets
,我发现我还是在为设置或管理页面编写大量的代码来创建标签界面。
引入 drift_editors
我制作了drift_editors
来减轻至少更新行的工作量。现在,我不再需要写这样的代码:
final database = ref.watch(databaseProvider);
final dao = database.missionsDao;
final value = ref.watch(missionProvider(missionId));
return SimpleScaffold(
title: 'Edit Mission',
body: value.when(
data: (final mission) => ListView(
shrinkWrap: true,
children: [
TextListTile(
value: mission.name,
onChanged: (final name) async {
await dao.editMission(
mission: mission,
companion: MissionsCompanion(name: Value(name)),
);
invalidateProviders(ref);
},
header: 'Mission name',
),
PointListTile(
point: Point(mission.x, mission.y),
onChanged: (final point) async {
await dao.editMission(
mission: mission,
companion: MissionsCompanion(
x: Value(point.x),
y: Value(point.y),
),
);
invalidateProviders(ref);
},
title: 'Initial coordinates',
),
],
),
error: ErrorListView.withPositional,
loading: LoadingWidget.new,
),
);
而是可以写这样的代码:
final database = ref.watch(databaseProvider);
final missions = database.missions;
final value = ref.watch(missionProvider(missionId));
return value.when(
data: (final mission) {
final id = mission.id;
return DriftEditorScreen(
columnHandlers: [
StringColumnHandler(
value: mission.name,
column: missions.name,
),
PointColumnHandler(
xColumn: missions.x,
yColumn: missions.y,
value: Point(mission.x, mission.y),
title: 'Initial coordinates',
),
],
title: 'Edit Mission',
database: database,
tableInfo: missions,
primaryKeyColumn: missions.id,
primaryKey: id,
onChanged: () => invalidateProviders(ref),
);
},
error: ErrorScreen.withPositional,
loading: LoadingScreen.new,
);
如果你更喜欢自己编写屏幕,可以直接使用 [ColumnsListView]
小部件。
完整示例
主要文件结构
假设你的项目结构如下:
lib/
├── main.dart
├── database/
│ ├── mission_dao.dart
│ └── mission_database.dart
└── widgets/
└── drift_editors_screen.dart
数据库定义
mission_database.dart
import 'package:drift/drift.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart' as sqflite;
part 'mission_database.g.dart';
class Missions extends Table {
IntColumn get id => integer().autoIncrement()();
TextColumn get name => text().withLength(min: 1, max: 100)();
RealColumn get x => real()();
RealColumn get y => real()();
}
@DriftDatabase(tables: [Missions])
class MyDatabase extends _$MyDatabase {
MyDatabase() : super(_openConnection());
static MyDatabase open() {
final instance = MyDatabase();
instance.into(instance.missions).insert(MissionsCompanion.insert(name: 'Default Mission', x: 0, y: 0));
return instance;
}
[@override](/user/override)
int get schemaVersion => 1;
}
LazyDatabase _openConnection() {
return LazyDatabase(() async {
final dbFolder = await getApplicationDocumentsDirectory();
final file = File('${dbFolder.path}/missions.db');
return sqflite.databaseFactoryIo.openDatabase(file.path);
});
}
mission_dao.dart
import 'package:my_project/database/mission_database.dart';
class MissionsDao {
final MyDatabase _db;
MissionsDao(this._db);
Future<void> editMission({required MissionsCompanion companion, required int id}) async {
await _db.update(_db.missions).replace(companion, where: 'id = ?', whereArgs: [id]);
}
}
编辑器屏幕
drift_editors_screen.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:drift_editors/drift_editors.dart';
import 'package:my_project/database/mission_database.dart';
import 'package:my_project/widgets/loading_screen.dart';
import 'package:my_project/widgets/error_screen.dart';
final databaseProvider = Provider((ref) => MyDatabase.open());
class DriftEditorScreen extends ConsumerWidget {
final List<ColumnHandler> columnHandlers;
final String title;
final MyDatabase database;
final TableInfo<Missions, dynamic> tableInfo;
final Column<Missions, dynamic> primaryKeyColumn;
final int primaryKey;
final VoidCallback onChanged;
DriftEditorScreen({
required this.columnHandlers,
required this.title,
required this.database,
required this.tableInfo,
required this.primaryKeyColumn,
required this.primaryKey,
required this.onChanged,
});
[@override](/user/override)
Widget build(BuildContext context, ScopedReader watch) {
final value = watch(missionProvider(primaryKey));
return value.when(
data: (final mission) {
return Scaffold(
appBar: AppBar(title: Text(title)),
body: DriftEditor(
columnHandlers: columnHandlers,
database: database,
tableInfo: tableInfo,
primaryKeyColumn: primaryKeyColumn,
primaryKey: primaryKey,
onChanged: onChanged,
),
);
},
error: (error, stackTrace) => ErrorScreen.withPositional(error, stackTrace),
loading: () => LoadingScreen(),
);
}
}
主文件
main.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:my_project/database/mission_database.dart';
import 'package:my_project/widgets/drift_editors_screen.dart';
void main() {
runApp(ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: DriftEditorScreenPage(),
);
}
}
class DriftEditorScreenPage extends ConsumerWidget {
[@override](/user/override)
Widget build(BuildContext context, ScopedReader watch) {
final database = watch(databaseProvider);
final missions = database.missions;
final missionId = 1; // 假设我们正在编辑ID为1的使命
return DriftEditorScreen(
columnHandlers: [
StringColumnHandler(
value: 'Default Mission', // 假设这是初始值
column: missions.name,
),
PointColumnHandler(
xColumn: missions.x,
yColumn: missions.y,
value: Point(0, 0), // 假设这是初始坐标
title: 'Initial coordinates',
),
],
title: 'Edit Mission',
database: database,
tableInfo: missions,
primaryKeyColumn: missions.id,
primaryKey: missionId,
onChanged: () {},
);
}
}
更多关于Flutter数据库编辑器插件drift_editors的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter数据库编辑器插件drift_editors的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用drift_editors
插件的一个示例。drift_editors
是一个用于与drift
(一个基于SQLite的Flutter数据库库)集成的数据库编辑器插件,它提供了图形界面来编辑数据库的内容。
首先,确保你的Flutter项目中已经包含了drift
和drift_dev
依赖项,以及drift_editors
插件。在pubspec.yaml
文件中添加以下依赖项:
dependencies:
flutter:
sdk: flutter
drift: ^x.y.z # 替换为最新版本号
drift_dev: ^x.y.z # 开发工具,仅在开发时使用
dev_dependencies:
build_runner: ^x.y.z
drift_generator: ^x.y.z
drift_editors: ^x.y.z # 添加drift_editors插件
然后,运行flutter pub get
来安装这些依赖项。
接下来,你需要设置drift
数据库。创建一个数据模型,并生成相应的数据库代码。例如,创建一个简单的User
表:
// user.dart
import 'package:drift/drift.dart';
part 'user.g.dart';
@DataClassName('User')
class Users extends Table {
IntColumn get id => integer().autoIncrement().primaryKey();
TextColumn get name => text().withDefault(Constant('Unknown'));
TextColumn get email => text().nullable();
}
运行flutter pub run build_runner build
来生成数据访问对象(DAO)和数据库类。
现在,你可以创建一个数据库实例并使用drift_editors
来编辑它。以下是一个完整的示例,展示如何在Flutter应用中集成drift_editors
:
// main.dart
import 'package:flutter/material.dart';
import 'package:drift/drift.dart';
import 'package:drift_editors/drift_editors.dart';
import 'user.dart';
import 'package:your_app_name/your_database.g.dart'; // 确保导入生成的数据库文件
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Drift Editors Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late DatabaseConnection _db;
@override
void initState() {
super.initState();
// 打开数据库连接
_db = DatabaseConnection.memory(); // 或者使用 DatabaseConnection.connect('path_to_db.sqlite')
final database = YourDatabase(_db);
database.createAllTables();
// 示例:插入一些初始数据
final userDao = database.userDao;
userDao.intoUsers().insertAll([
UserCompanion.insert(name: Value('Alice'), email: Value('alice@example.com')),
UserCompanion.insert(name: Value('Bob'), email: Value('bob@example.com')),
]);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Drift Editors Demo'),
),
body: Center(
child: ElevatedButton(
onPressed: () async {
// 打开 Drift Editors 界面
final result = await showDialog<bool>(
context: context,
builder: (context) {
return DriftEditorsDialog(
databaseConnection: _db,
title: 'Edit Database',
);
},
);
if (result == true) {
// 用户点击了保存按钮,可以在这里处理保存后的逻辑
print('Database edited and saved.');
}
},
child: Text('Open Database Editor'),
),
),
);
}
@override
void dispose() {
_db.close();
super.dispose();
}
}
在上面的代码中,我们创建了一个简单的Flutter应用,其中包含一个按钮,点击该按钮会打开一个DriftEditorsDialog
对话框,允许用户编辑数据库。注意,这里使用的是内存数据库(DatabaseConnection.memory()
),你可以根据需要更改为文件数据库。
请确保将your_app_name
和your_database.g.dart
替换为你的实际项目名和生成的数据库文件名。
这个示例展示了如何在Flutter应用中集成drift_editors
插件,并允许用户通过图形界面编辑数据库。