Flutter&Python项目实战: 从0到1实现背单词App(4)App端主框架和数据库创建

403 阅读2分钟

有一句古老的工程格言:工期短、质量好、价格便宜,这三项里面你最多只能同时做到两项。

后端接口已经有了, 接下来将开始前端的开发, 我们依然按照从框架到细节的步骤来coding. 整个前端项目是建立在getx框架上的, 不了解该框架的可以去github瞅瞅.

1. 项目依赖

笔者使用AndroidStudio进行项目构建和开发, 大家可以选择自己喜欢的开发工具.

如果您选择使用命令行构建项目请使用 flutter create --platforms=windows,macos,linux .添加多平台支持(当然也可以选择不支持).

下面是pubspec.yaml中项目所依赖的第三方:

dependencies:
  flutter:
    sdk: flutter
  # 状态管理
  get: ^4.6.5
  # json 解析
  json_annotation: ^4.5.0
  # 日期格式化
  date_format: ^2.0.6
  # loading 动画
  flutter_easyloading: ^3.0.3
  # sqlite 数据存储
  sqflite: ^2.0.3
  # csv 文件解析
  csv: ^5.0.1
  # 刷新
  # https://pub.dev/packages/pull_to_refresh
  # 适配 3.0: https://github.com/peng8350/flutter_pulltorefresh/issues/591
  pull_to_refresh:
    git:
      url: https://github.com/miquelbeltran/flutter_pulltorefresh
  # 扩展函数 支持元祖, zip等
  more: ^3.5.0
  # 语音
  flutter_tts: ^3.5.0
  # 网络检测
  connectivity_plus: ^2.3.5

dev_dependencies:
  flutter_test:
    sdk: flutter
  json_serializable: ^6.1.5
  build_runner: ^2.1.8

如果您是纯小白, 建议先从官方文档开始~

2. 项目文件夹结构

下面的文件夹目录大家可以参考:

/// lib/
components  // 组件
    | constants // 常量
    | extensions // 扩展
    | mixins    // 混入
models      // 数据
net         // 网络
pages       // 业务代码
route       // 路由
services    // 服务
main.dart   // 入口函数

3. 初始化数据库

我们需要做以下几件事:

  1. 建立数据库.
  2. 创建图书表, 单词表, 背诵历史表等.

首先, 在services.db.dart中构建DB类, 用于处理数据库业务:

/// services.db.dart
class DB {
  late Database fisher;

  /// 单例
  static final shared = DB();

  initialize() async {
    fisher = await openDatabase('fisher.db', version: 1, onCreate: _onCreateDatabase); // 这里忽略了升级
  }
  
  /// 创建数据库
  _onCreateDatabase(Database db, int version) async {
    final sqlVersion = FisherSQLVersion.values[version - 1];
    _execute(db.batch(), sqlVersion.sqlList);
  }

  /// 执行升级语句
  _execute(Batch batch, List<String> sqlList) {
    for (var sql in sqlList) {
      batch.execute(sql);
    }
    batch.commit();
  }
}

此外, 在services.sql.dart中构建sql语句:

/// services.sql.dart
/// 单词表
enum FisherTable {
  /// 单词本
  book,

  /// 阅读历史
  history,

  /// 收藏
  collection
}

enum FisherSQLVersion {
  version_1;

  /// 创建语句
  List<String> get sqlList {
    switch (this) {
      case FisherSQLVersion.version_1:
        return [
          'CREATE TABLE IF NOT EXISTS ${FisherTable.book.name} ('
              'id INTEGER PRIMARY KEY, '
              'name TEXT NOT NULL, '
              'readStatus INTEGER DEFAULT 0)',
          'CREATE TABLE IF NOT EXISTS ${FisherTable.collection.name} ('
              'id INTEGER PRIMARY KEY AUTOINCREMENT, '
              'bookId INTEGER NOT NULL, '
              'wordId INTEGER NOT NULL)',
          'CREATE TABLE IF NOT EXISTS ${FisherTable.history.name} ('
              'id INTEGER PRIMARY KEY AUTOINCREMENT, '
              'bookId INTEGER NOT NULL, '
              'wordId INTEGER NOT NULL, '
              'timestamp INTEGER NOT NULL)',
        ];
    }
  }

  /// 升级语句
  List<String> get upgradeSqlList {
    return [];
  }
}

最后, 在入口函数中初始化数据库(自动构建表):

/// main.dart
void main() async {
  WidgetsFlutterBinding.ensureInitialized(); // 重要哦~
  await DB.shared.initialize();
  runApp(App());
}

上面的sql语句都很简单, 大家不用担心~. 单词表需要运行时创建, 后面咱们还会聊到.

至此, 我们的数据库就算创建完成了, 项目运行时会自动创建数据库文件(fisher.db), 大家可以通过文件管理器找到该文件, 然后通过数据库客户端(如Navicat)打开查看.

下一章, 我们将构建背单词的设置页, 嘿嘿终于开始写点业务代码了


代码已开源: github.com/oooooocean/…, 如果觉得有帮助, 请给个Star, 鼓励下作者.

如果您有关于数据库创建/升级的疑问, 或者遇到什么问题, 欢迎加群和作者讨论: