Flutter项目模板插件flutter_boilerplate的使用

发布于 1周前 作者 ionicwang 来自 Flutter

Flutter项目模板插件flutter_boilerplate的使用

简介

flutter_boilerplate 是一个用于快速启动 Flutter 应用开发的项目模板插件。它包含现成的项目结构、基础服务文件和可直接使用的部件。

支持

  • Android: SDK 21+
  • iOS: iOS 9+

安装

pubspec.yaml 文件中添加以下依赖:

dev_dependencies:
  flutter_boilerplate: ^0.0.6

然后运行以下命令以安装依赖项:

flutter pub get

初始化基础项目

运行以下命令以初始化基本项目结构:

flutter pub run flutter_boilerplate:init

注意:仅在新项目中运行此命令。该命令会替换项目的 lib 文件夹和 pubspec.yaml 文件。初始化后别忘了设置图标、启动画面和包名(步骤详见相应的 YAML 文件)。运行 init 命令后,所有必需的 YAML 文件将直接导入到你的项目中!

包含的模块/包/插件

模块名称 包版本 最新版本
响应式框架 0.2.0 响应式框架
Dio 4.0.6 Dio
Get Storage 2.0.3 Get Storage
路径提供者 2.0.11 路径提供者

可直接使用的服务部件

HttpWidget

HttpWidget 是一个可以用来处理 HTTP 请求的部件。以下是其使用示例:

HttpWidget(
  key: const ValueKey(ApiStrings.usersAPIString),
  errorWidget: CustomLoaders.circularLoader(),
  loader:  CustomLoaders.circularLoader(),
  api: hC.getUsers(),
  useCache: true,
  apiURL: ApiStrings.usersAPIString,
  builder: (data) {
    List<UserDTO> users = (data as List).map((e) => UserDTO.fromJson(e)).toList();
    return ListView.builder(
      itemCount: users.length,
      shrinkWrap: true,
      physics: const ClampingScrollPhysics(),
      itemBuilder: (context, index) {
        return ListTile(
          leading: Text('${users[index].id}'),
          title: Text('${users[index].name}'),
          subtitle: Text('${users[index].email}'),
        );
      },
    );
  },
)

更多使用案例请参见 example 应用。

StorageListenerWidget

StorageListenerWidget 用于监听存储变化。以下是其使用示例:

StorageListenerWidget(
  storage: AppStorage.storage,
  listenKey: StorageKeys.randomStringKey,
  builder: (value) {
    return Text('RANDOM STRING :-  $value');
  },
),

更多使用案例请参见 example 应用。

可直接使用的服务文件

BaseHttp

BaseHttp 提供了一些常用的方法,如存储和获取 token、检查认证状态等:

class BaseHttp {
  Future<void> storeToken(String token);
  Future<String?> getToken();
  Future<bool> checkAuthStatus();
  Future<void> storeAuthData(Map<String, dynamic> data);
  Future<Map<String, dynamic>?> getAuthData();
  Future<void> storeDefaultHeaders(Map<String, String> headers);
  Future<Map<String, String>?> getDefaultHeaders();
  Stream<dynamic> getStream(String url);
  Future<dynamic> get(String url);
  Future<dynamic> post(String url, {Map<String, dynamic>? body});
}

BaseInterceptor

BaseInterceptor 默认与 BaseHttp 实例一起使用,提供了一些方法:

class BaseInterceptor {
  Map<String, String> getHeaders();
  void onError(error);
  void onRequest(requestOptions);
  void onResponse(response);
}

Log

kLog 用于日志记录,提供了过滤日志、写入日志文件、分配标签和类型等功能:

void logsExample() {
  kLog("on info", logStatus: LogStatus.INFO, tag: 'log_example');
  kLog("on error", logStatus: LogStatus.ERROR, tag: 'log_example');
  kLog("on warning", logStatus: LogStatus.WARNING, tag: 'log_example');
}

Storage

GetStorage 用于 StorageService,提供了存储和检索数据的功能:

class StorageService {
  Future<void> saveValue(String key, dynamic value);
  Future<void> updateValue(String key, dynamic value);
  Future<void> updateNewValue(String key, dynamic value);
  Future<dynamic> getValue(String key);
  Future<bool> hasData(String key);
  Future<void> removeValue(String key);
  Future<void> clearStorage();
}

Navigation

navigationService 提供了多种导航方法,如跳转页面、返回等:

class NavigationService {
  BuildContext context;
  void to(String route);
  void back();
  void replace(String route);
  void clearStack();
}

Utils

Utils 文件夹中包含一些实用工具文件,如字符串扩展、生命周期处理器等:

// extensions.dart
extension StringExtensions on String {
  String imagePathToBase64String();
  Color toColor();
  String toCapitalized();
}

// initializer.dart
class Initializer {
  static void init(VoidCallback callback);
}

// lifecycle_handler.dart
class LifecycleHandler {
  static void handleLifecycle();
}

// loaders.dart
class CustomLoaders {
  static Widget circularLoader();
  static Dialog loaderDialog();
  static Widget imageLoadingBuilder();
  static bool isLoading();
  static void setLoading(bool loading);
}

// utils.dart
class Utils {
  static String getFileSize(File file);
  static String getRandomString();
}

// validators.dart
class Validators {
  static bool validateEmpty(String value);
  static bool validateEmail(String value);
  static bool validateOTPCode(String value);
}

可直接使用的常量文件

Assets

abstract class Assets {
  // 例如:
  // static const exampleAsset = 'assets/images/example_assets.svg';
}

ApiStrings

abstract class ApiStrings {
  // 例如:
  // static const loginAPIString = 'example/login';
}

Constants

abstract class Constants {
  static const String appName = '';
  static Environment env = Staging();
}

StorageKeys

abstract class StorageKeys {
  // 例如:
  // static const userNameKey = 'user_name';
}

Strings

abstract class Strings {
  static const String appName = Constants.appName;

  // 认证模块
  static const welcomeBack = '欢迎回来!';
  static const getStarted = '开始';
  static const loginToContinue = '登录以继续';
  static const createAnAccount = '创建账户';
  
  // 输入字段验证
  static const String cantBeEmpty = '不能为空。';
  static const String fieldCantBeEmpty = '字段 $cantBeEmpty';
  static const String enterValid = '请输入有效的';
  static const otpValidation = '无效的验证码';

  // 全名
  static const fullName = '全名';
  static const enterYourFullName = '输入您的全名';

  // 邮箱地址
  static const emailAddress = '邮箱地址';
  static const enterYourEmailAddress = '输入您的邮箱地址';
  static const String emailCantBeEmpty = '邮箱 $cantBeEmpty';
  static const String enterValidEmail = '$enterValid 邮箱。';

  // 密码
  static const String password = '密码';
  static const enterYourPassword = '输入您的密码';
  static const forgotPassword = '忘记密码';
  static const forgotPasswordDescription = '输入您的注册邮箱以接收重置密码的说明并检查您的邮箱';
  static const String confirmPassword = '确认密码';
  static const String enterPassword = '输入密码';
  static const String passwordCantBeEmpty = '$password $cantBeEmpty';
  static const String passwordValidation = '$password 必须至少有6个字符。';
  static const confirmPasswordValidation = '$password 和确认密码必须相同。';
  static const newPassword = '新密码';
  static const createNewPassword = '现在您可以创建一个新密码';
  static const reEnterYourPassword = '重新输入您的新密码';

  // 手机号码
  static const mobileNumber = '手机号码';
  static const String emailOrMobile = '$emailAddress 或 $mobileNumber';
  static const String numberCantBeEmpty = '$emailOrMobile $cantBeEmpty';
  static const String enterValidNumber = '$enterValid $mobileNumber。';

  // 验证码
  static const String sendCode = '发送验证码';
  static const String enterVerificationCode = '输入验证码';
  static const verificationCodeSendToEmail = '我们已向您的邮箱发送验证码以验证您的邮箱地址';
  static const resendOTP = '重新发送验证码';
  static const verify = '验证';

  // 登录/注册
  static const logIn = '登录';
  static const signUp = '注册';
  static const alreadyHaveAnAccount = '您已经有账户了吗?';
  static const notHaveAnAccount = '还没有账户吗?';
  static const orContinueWith = '或继续使用';
  static const or = '或';
  static const google = 'Google';
  static const apple = 'Apple';
  static const signInWithGoogle = '使用 Google 登录';
  static const signInWithApple = '使用 Apple 登录';

  // 互联网错误字符串
  static const unknownError = '未知错误!请稍后再试。';
  static const connectionTimeout = '连接超时。请稍后再试。';
  static const noConnection = '无网络连接。请打开您的网络!';
  static const unauthorized = '未授权。请重新登录!';

  // 全局字符串
  static const String ok = '确定';
  static const String error = '错误';
  static const String noInternet = '无网络。请稍后再试。';
  static const String logOut = '登出';
  static const String retry = '重试';
  static const String confirm = '确认';
  static const String somethingWentWrong = '出错啦。';
  static const String home = '首页';

  static const gallery = '相册';
  static const camera = '相机';
  static const mobile = '手机';
  static const from = '来自';
  static const toCap = '至';
  static const success = '成功';
  static const checkboxValidation = '示例复选框验证信息';
}

Theme

abstract class Theme {
  // 添加您的应用主题
}

可直接使用的环境文件

ENV

enum ENV { staging, production }

abstract class Environment {
  String apiUrl();
  String socketUrl();
  String buildNumber();
  String appVersion();
  int isBeta();
}

TYPES

class Production extends Environment {
  @override
  String apiUrl() {
    return "";
  }

  @override
  String socketUrl() {
    return "";
  }

  @override
  String buildNumber() {
    return "1";
  }

  @override
  String appVersion() {
    return "1.0.0";
  }

  @override
  int isBeta() {
    return 0;
  }
}

可直接使用的路由服务文件

abstract class Routes {
  static const INITIAL = '/initial';
}

abstract class RouteServices {
  const RouteServices._();

  static const STARTING_POINT = Routes.INITIAL;

  static Map<String, Widget Function(BuildContext context)> routes = {
    Routes.INITIAL: (context) => const InitialPage(),
  };

  static PageRoute onGenerateRoute(settings, context) {
    return MaterialPageRoute(builder: (_) => RouteServices.routes[settings.name]!(context));
  }
}

如何导入可选模块

运行以下命令以添加可选模块:

flutter pub run flutter_boilerplate:add &lt;arguments&gt;

注意:你必须手动导入并为相应的包进行原生配置。以下服务模块将被添加到项目中:

模块名称 参数 包版本 最新版本
音频播放器 audio_player 3.0.5 音频播放器
Apple Sign-in apple_authentication 4.2.0 Apple Sign-in
Google Sign-in google_authentication 5.4.2 Google Sign-in
语音识别 speech_to_text 6.1.0 语音识别
文本转语音 text_to_speech 3.5.3 文本转语音
图片压缩* image_service 6.1.0 图片压缩

项目结构

|-- lib
|   |-- common
|   |   |-- data
|   |   |   |-- assets
|   |   |   |   '-- assets.dart
|   |   |   |-- constants
|   |   |   |   |-- api_strings.dart
|   |   |   |   |-- constants.dart
|   |   |   |   '-- storage_keys.dart
|   |   |   |-- strings
|   |   |   |   '-- strings.dart
|   |   |   '-- theme
|   |   |       '-- theme.dart
|   |   |-- env
|   |   |   |-- environment.dart
|   |   |   '-- types
|   |   |       |-- production.env.dart
|   |   |       '-- staging.env.dart
|   |   |-- routes
|   |   |   '-- route_service.dart
|   |   |-- services
|   |   |   |-- http
|   |   |   |   |-- base_http.dart
|   |   |   |   '-- base_interceptor.dart
|   |   |   |-- log
|   |   |   |   '-- log.dart
|   |   |   |-- navigation
|   |   |   |   '-- navigation.dart
|   |   |   '-- storage
|   |   |       '-- storage.dart
|   |   |-- utils
|   |   |   |-- extensions.dart
|   |   |   |-- initializer.dart
|   |   |   |-- lifecycle_handler.dart
|   |   |   |-- loaders.dart
|   |   |   |-- snackbars.dart
|   |   |   |-- utils.dart
|   |   |   '-- validators.dart
|   |   '-- widgets
|   |       |-- compute
|   |       |   |-- compute_list_widget.dart
|   |       |   '-- compute_widget.dart
|   |       |-- http
|   |       |   '-- http_widget.dart
|   |       |-- image
|   |       |   '-- image_widget.dart
|   |       '-- listener
|   |           '-- storage_listener_widget.dart
|   |-- main.dart
|   '-- modules
|       '-- initial
|           '-- pages
|               |-- initial_material_app.dart
|               '-- initial_page.dart

更多关于Flutter项目模板插件flutter_boilerplate的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter项目模板插件flutter_boilerplate的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中集成和使用flutter_boilerplate插件的详细步骤和代码案例。flutter_boilerplate是一个流行的Flutter项目模板,它提供了一套预定义的架构和工具,以帮助开发者快速启动Flutter应用开发。

1. 添加依赖

首先,确保你的Flutter项目已经创建。然后在pubspec.yaml文件中添加flutter_boilerplate的依赖(如果它是一个公开发布的包,但请注意,flutter_boilerplate可能更多是指一个通用的模板结构,而非一个具体的包)。这里假设你有一个类似模板的依赖或者你自己有一个模板仓库。

dependencies:
  flutter:
    sdk: flutter
  # 假设有一个模板相关的包,这里用flutter_boilerplate_template代替实际包名
  flutter_boilerplate_template: ^x.y.z

然后运行flutter pub get来安装依赖。

2. 项目结构

flutter_boilerplate通常会有一个预定义的项目结构。假设你已经克隆了一个模板仓库或者下载了一个模板项目,你的项目结构可能类似于这样:

my_flutter_app/
├── android/
├── ios/
├── lib/
│   ├── main.dart
│   ├── app/
│   │   ├── app.dart
│   │   ├── routes/
│   │   │   └── routes.dart
│   │   ├── services/
│   │   │   └── api_service.dart
│   │   ├── models/
│   │   │   └── user_model.dart
│   │   └── widgets/
│   │       └── reusable_widget.dart
├── test/
└── pubspec.yaml

3. 集成核心组件

main.dart

main.dart通常是应用的入口文件。它配置了MaterialApp或者CupertinoApp,并设置了路由。

import 'package:flutter/material.dart';
import 'package:flutter_boilerplate_template/app/app.dart'; // 假设模板包提供了App组件

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Boilerplate',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: App(), // 使用模板提供的App组件
    );
  }
}

app.dart

app.dart文件通常定义了应用的核心逻辑,比如依赖注入和路由设置。

import 'package:flutter/material.dart';
import 'package:flutter_boilerplate_template/routes/routes.dart'; // 假设模板包提供了路由配置

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Navigator(
      initialRoute: '/',
      onGenerateRoute: Routes.generateRoute,
    );
  }
}

routes.dart

routes.dart文件定义了应用的路由配置。

import 'package:flutter/material.dart';
import '../widgets/reusable_widget.dart'; // 假设有一个可复用的widget

class Routes {
  static Route<dynamic> generateRoute(RouteSettings settings) {
    switch (settings.name) {
      case '/':
        return MaterialPageRoute(builder: (_) => ReusableWidget());
      default:
        return MaterialPageRoute(builder: (_) => Scaffold(body: Center(child: Text('404'))));
    }
  }
}

reusable_widget.dart

这是一个简单的可复用widget示例。

import 'package:flutter/material.dart';

class ReusableWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Reusable Widget'),
      ),
      body: Center(
        child: Text('This is a reusable widget!'),
      ),
    );
  }
}

4. 运行项目

确保所有文件都已正确配置后,你可以通过运行flutter run来启动你的Flutter应用。

flutter run

总结

上述代码展示了如何在一个Flutter项目中集成和使用一个假设的flutter_boilerplate模板。实际使用中,你可能需要根据具体的模板文档进行微调。大多数模板会提供详细的README文件,指导你如何设置和使用模板中的各个组件。

回到顶部