Flutter 样板代码


Logo

Flutter 样板项目

Fork 此项目,然后开始你的项目,已有大量准备工作!

基础项目,饱含爱意制作。包含 CRUD、模式等更多内容!

报告 Bug
·
请求功能

目录

如何使用

步骤 1

使用下面的链接下载或克隆此仓库

https://github.com/PingAK9/init-flutter.git

步骤 2

转到项目根目录,在控制台中执行以下命令以获取所需的依赖项

flutter pub get 

步骤 3

此项目使用 `inject` 库,该库支持代码生成,请执行以下命令生成文件

flutter packages pub run build_runner build --delete-conflicting-outputs

或使用 watch 命令以自动同步源代码

flutter packages pub run build_runner watch

隐藏生成的文件

为了隐藏生成的文件,请导航到 `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

代码约定

依赖项

助手

  • logger: 小巧、易用且可扩展的日志记录器,可打印漂亮的日志。

  • url_launcher: 一个用于在移动平台启动 URL 的 Flutter 插件。支持 iOS、Android、Web、Windows、macOS 和 Linux。

  • auto_route: 自动路由生成器,路由管理器

  • get: Snackbar、导航、主题、助手函数

  • intl: 此包提供国际化和本地化功能,包括消息翻译、复数和性别、日期/数字格式化和解析,以及双向文本。

  • shared_preferences: 用于读写简单键值对的 Flutter 插件。在 iOS 上包装 NSUserDefaults,在 Android 上包装 SharedPreferences。

其他: hive, sqflite

HTTP, API

  • http: 一个可组合的、基于 Future 的 HTTP 请求库。

此外,您还可以使用您喜爱的包之一 DIO

Flutter Fire

Flutter 的官方 Firebase 插件。登录、分析、崩溃报告、存储、Firestore

状态管理

  • provider: **推荐方法。
    其他推荐**

其他喜欢的包

  • rxdart: RxDart 为 Dart Streams 和 StreamControllers 增加了附加功能。用作 bloc 模式
  • flutter_bloc: 使 bloc 和 cubit 易于集成到 Flutter 中的小部件。 了解更多
  • RiverPod: 此项目可以被视为 provider 的重写,以便进行不可能的改进。
  • Get: 一个简化的响应式状态管理解决方案。
  • stacked: 此架构最初是 MVVM 的一个版本。

小部件

图片

代码结构

这是 Flutter 提供的核心文件夹结构。

flutter-app/
|- android
|- ios
|- lib
|- modules
|- test

这是我们在此项目中使用的文件夹结构

lib/
|- code/
|- data/
|- _devmode/
  |- mock/
  |- view/
  |- widget/
|- services/
|- feature/
  |- dashboard/
    |- widget/
    |- controller
    |- dashboard_screen.dart
  |- home/
  |- login/
|- plugins/
|- routing/
|- shared/
  |- widget/
  |- controller/
  |- models/
  |- view/
|- main.dart
|- modules

以下是此项目中核心模块的文件夹结构

ping9/
|- code/
|- dialog/
|- theme/
|- widget/
|- view/

现在,让我们深入 `lib` 文件夹,其中包含应用程序的主要代码。

主题

如果我们的应用程序支持浅色和深色主题,并且这些主题是自定义主题。我们将为每种小部件类型添加所有必需的颜色。我们将创建另一个文件 theme_config.dart,其中描述了所有与主题相关的常量。

我们需要为每个主题自定义两样东西。
我们需要创建两个文件 light_theme.dart、dark_theme.dart,在其中我们将为每种小部件类型添加所有必需的颜色

  • ThemeData (样式): fontFamily, primaryColor, brightness, textTheme, inputDecorationTheme, buttonTheme
  • ColorScheme: 为 ColorScheme 创建扩展,为暗模式和亮模式添加任何自定义颜色。这样,当您运行时更改主题时,它将更新小部件

配置

此目录包含/配置所有应用程序级别的常量。如下面的示例所示,为每种类型创建了一个单独的文件

  • assest_path.dart: 尽管我们在 pubspec.yaml 中描述了资源路径,但要在应用程序中使用该资源,我们需要在任何小部件中提供其相对路径。
    如果我们把所有的资源相对路径都放在一个文件中,那么获取所有路径并在将来需要时更新路径将变得更加容易。
  • app_constants.dart: 这里将包含我们所有的应用程序常量,并且这对于每个应用程序都是不同的。

常量文件夹看起来是这样的

Config/
|- constants.dart
|- app_config.dart
|- device_info.dart
|- preferences.dart
|- content.dart

路由

此文件包含您应用程序的所有路由。
使用 auto_router 生成路由设置和 Router

import 'package:flutter/material.dart';

import 'ui/home/home.dart';
import 'ui/login/login.dart';
import 'ui/splash/splash.dart';

class Routes {
  Routes._();

  //static variables
  static const String splash = '/splash';
  static const String login = '/login';
  static const String home = '/home';

  static final routes = <String, WidgetBuilder>{
    splash: (BuildContext context) => SplashScreen(),
    login: (BuildContext context) => LoginScreen(),
    home: (BuildContext context) => HomeScreen(),
  };
}

如果您只使用一个导航器

ExtendedNavigator.root.push(..)

使用 context 进行堆栈导航

ExtendedNavigator.of(context).push(...)
// or
context.navigator.push(...)
context.rootNavigator.push(...)
// give your navigator a name
ExtendedNavigator(router: Router(), name: "nestedNav")
//call it by its name
ExtendedNavigator.named("nestedNav").push(...)

更多信息 – auto_route

服务

您应用程序的所有业务逻辑都将放在此目录中,它代表您应用程序的数据层。它细分为三个目录 localnetworkshared_perf,每个目录包含特定于域的逻辑。由于每一层都独立存在,因此更容易进行单元测试。UI 和数据层之间的通信是通过中央存储库处理的。

Services/
|- analytics_service.dart
|- authentication_service.dart
|- cloud_storage_service.dart
|- dialog_service.dart
|- firestore_service.dart
|- google_service.dart
|- shared_preference_service.dart
|- theme_service.dart
|- user_service.dart

使用 **依赖注入** 模式来管理所有服务。

void setupLocator() {
  Get.lazyPut(() => DialogService());
  Get.lazyPut(() => UserService());
  Get.lazyPut(() => AuthenticationService());
  Get.lazyPut(() => FirestoreService());
  Get.lazyPut(() => UserDefaults());
  Get.lazyPut(() => CloudStorageService());
  Get.lazyPut(() => ThemeService());
  Get.lazyPut(() => TabBarViewModel());
  Get.lazyPut(() => ConstantData());
}

功能

将应用程序拆分为功能。所有模块和核心功能都应包含这四个文件夹,以将业务逻辑与 UI 分离。

|- feature/
  |- dashboard/
    |- widget/
    |- controller
    |- dashboard_screen.dart
  |- home/
  |- login/

UI/小部件

包含跨多个屏幕共享的通用 widget。例如,Button、TextField 等。

widgets/
|- form
|- block
|- button
| - ...

视图模型

Store 是您所有应用程序状态在 Flutter 中存在的地方。Store 基本上是一个位于 widget 树顶部的 widget,它通过特殊方法向下传递其数据。对于多个 store,将为每个 store 创建一个单独的文件夹,如下面的示例所示

viewmodels/
|- player-viewmodel
|- manager-viewmodel
|- rating-viewmodel
|- login-viewmodel
|- user-viewmodel
|- squad-viewmodel
  • FeatureNameScreen.dart
  • Controller/ 此文件夹包含存储库文件,用于编写服务调用和状态管理代码。 推荐使用 **provider** > **bloc 模式 (rxdart)**
  • Widget/ 此文件夹包含所有用户可见的屏幕 UI 小部件。
  • Models/ 此文件夹包含需要在仪表板屏幕上显示的数据模型。

主入口

这是应用程序的起点。所有应用程序级别的配置都在此文件中定义,即主题、路由、标题、方向等。
使用 Get 包进行主题、导航、snackbar…

  • 在运行应用程序之前进行初始化、设置

Future main() async{
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp()
  setupLocator();
  await AppConfig.instance.appSetup(BuildFlavor.development);
  runApp(MyApp());
}
  • 使用 MaterialApp 包装器运行应用程序
    如果您使用 Get 包,您应该使用 GetMaterialApp 进行设置
    还需要设置:Toash、Theme、DialogService、Router、localizations

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: Strings.appName,
      theme: themeData,
      routes: Routes.routes,
      home: SplashScreen(),
    );
  }
}

您的代码结构看起来像

Wiki

查看 wiki 以获取更多信息

GitHub

查看 Github