GeniusArchitecture
这是使用 Provider、Firebase、Dio 和 Robert C Martin 清洁架构的一些基本原理创建的 Flutter 样板项目。
入门
该样板是一个最小化的实现,可用于创建新项目或库。它带有一系列基本组件,例如应用程序架构、主题和必要的依赖项。该存储库代码可用作初始化程序,以快速构建新项目并缩短开发时间。
如何使用
步骤 1
使用下面的链接下载或克隆此仓库
https://github.com/GeniusCrew-B-V/genius-architecture-boilerplate.git
步骤 2
转到项目根目录,在控制台中执行以下命令以获取所需的依赖项
flutter pub get
步骤 3:通过项目范围的搜索并用您想要的名称替换“com.baseprojectsrl.baseproject”来更改包名
步骤 4
此项目使用代码生成来生成域/网络模型和应用程序本地化,请执行以下命令来生成文件
flutter packages pub run build_runner build --delete-conflicting-outputs
或使用 watch 命令以自动同步源代码
flutter packages pub run build_runner watch
步骤 5
前往 Firebase,创建一个新项目,进行配置,并将 GoogleServices-Info.plist 和 google-services.json 放在正确的位置,如果您跳过此步骤,应用程序将无法运行
隐藏生成的文件
为了隐藏生成的文件,请导航到 `Android Studio` -> `Preferences` -> `Editor` -> `File Types` 并在 `ignore files and folders` 部分粘贴以下行
*.inject.summary;*.inject.dart;*.g.dart;
在 Visual Studio Code 中,导航到 `Preferences` -> `Settings` 并搜索 `Files:Exclude`。添加以下模式
**/*.inject.summary
**/*.inject.dart
**/*.g.dart
样板项目功能
- 启动屏
- 惰性加载列表
- 登录
- 首页
- 路由
- 主题
- Dio
- 数据库
- Provider (状态管理)
- 验证
- 代码生成
- 依赖注入
- 深色主题支持
- 多语言支持
文件夹结构
这是我们在此项目中使用的文件夹结构
lib/
|- dev/
|- main.dart
|- i18n/
|- prod/
|- main.dart
|- resources/
|- src/
|- base
|- home_page
|- login
|- post_detail
|- profile_page
|- signup
|- start
|- updates
|- app.dart
现在,让我们深入 `lib` 文件夹,其中包含应用程序的主要代码。
1- dev - This is where the starting point of the application in case we want to work in a hipotetycal
development enviroment
2- i18n - Here we have all the .yaml files for each localization that we would need
3- prod - This is where the starting point of the application in case we want to work in a hipotetycal
production enviroment
4- resources - Here we have all the possible resources needed (Sizes,Image references etc.)
5- src - This is where we develop the app itself
1- base - Base feature is where we manage the whole app which isn't specifically feature-related, and
instead it's app related. It contains all the non-feature releated data
2- home_page - Home page feature
3- login - Login page feature
4- post_detail - Post detail page feature
5- profile_page - Profile page feature
6- signup - Signup page feature
7- start - Start feature is the first feature always launcher, it cointains basic navigation and auth
capabilities
8- updates- Updates page feature
9- app.dart - This is the real starting point of the application, where we inject all the
dependencies and run the app
功能结构
每个功能都遵循清洁架构路径的主要原则。
feature/
|- data
|- di
|- domain
|- ui
数据层
数据层包含数据源代码,例如 REST API、本地/远程数据库访问或任何其他数据源。在这里,我们遵循一个抽象类的系统,以便遵循域层中定义的方法签名。这会使事情稍微复杂化,但允许我们拥有健壮的代码,并且也有助于测试/调试阶段。
data/
|- source/
|- feature_remote_data_source.dart
|- feature_remote_data_source_impl.dart
|- feature_repository_impl.dart
依赖注入 (DI)
这是我们让一个类独立于其自身依赖项的地方。这将使我们能够以更易于管理的方式分离应用程序的不同部分,因为每个类可以在任何给定时间调用它所需的任何依赖项。
di/
|- feature_providers.dart
领域层
Domain 文件夹包含用于绘制和组织我们数据以及数据层中实现函数的签名的模型。这基本上使域层成为数据层和 UI/逻辑之间的“粘合剂”。
di/
|- model/
|- request_model.dart
|- response_model.dart
|- feature_repository.dart
UI
在 UI 文件夹中,我们管理页面/导航/小部件/状态管理(ViewModel)。
-
Pages 由我们正在处理的功能中包含的页面组成。它由该功能相关的较小小部件构建而成。
-
Navigator 是我们在该功能内添加导航逻辑的地方,它允许我们在页面之间移动。
-
ViewModel 是我们管理这些页面和整个功能的状态以及业务逻辑的地方。
ui/
|- model
|- navigator
|- pages
|- viewmodel
|- widget
App.dart
这是应用程序的起点。所有应用程序级别的配置均在此文件中定义,例如主题、标题、方向等。可以通过使用 AppConfig 类来配置应用程序的行为,例如风味、端点等。在这种情况下,我们使用 dev/main.dart 和 prod/main.dart 来处理这些事情。
dev/main.dart
import 'package:flutter/material.dart';
import '../src/app.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
mainCommon(
host: "https://31cae3b4-9771-4151-bdb2-41437d3b17ec.mock.pstmn.io",
isProd: false,
);
}
app.dart
import 'dart:io';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_displaymode/flutter_displaymode.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../resources/app_config.dart';
import 'base/settings/di/theme_providers.dart';
import 'base/settings/ui/viewmodel/theme_viewmodel.dart';
import 'base/token/di/token_providers.dart';
import 'base/widget/ui/custom_circular_progress_indicator.dart';
import 'start/di/start_page_providers.dart';
import 'start/ui/navigator/start_page_navigator.dart';
void mainCommon({required String host, required bool isProd, required String onesignalAppID}) async {
await WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
if(Platform.isAndroid) {
await FlutterDisplayMode.setHighRefreshRate();
}
final prefs = await SharedPreferences.getInstance();
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]).then(
(value) => runApp(
MultiProvider(
providers: themePageProviders(prefs),
builder: (context, __) {
final themeViewModel = context.watch<ThemeViewModel>();
return App(
host: host,
isProd: isProd,
themeViewModel: themeViewModel,
);
},
),
),
);
}
GeniusCrew B.V
Van Coothplein 53
4811 ND, Breda
荷兰
