[Flutter]创建一个私有包并使用

在Flutter中创建一个自己的私有组件(通常称为包或库),并通过Dart的包管理工具pub进行使用。

一、创建一个新的Flutter包

1.使用命令行创建

使用Flutter命令行工具来创建一个新的包:

Dart 复制代码
$ flutter create --template=package my_private_package

这将创建一个名为my_private_package的新目录,其中包含Dart的包标准结构。

2.使用Android Studio创建

New Flutter Project -> 选择项目类型为"Package"

3.默认项目结构

默认文件和单元测试

LICENSE & CHANGELOG.md

pubspec.yaml

Dart 复制代码
name: my_private_package
description: "A new Flutter project."
version: 0.0.1
homepage:

environment:
  sdk: '>=3.3.3 <4.0.0'
  flutter: ">=1.17.0"

dependencies:
  flutter:
    sdk: flutter

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^3.0.0

# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec

# The following section is specific to Flutter packages.
flutter:

  # To add assets to your package, add an assets section, like this:
  # assets:
  #   - images/a_dot_burr.jpeg
  #   - images/a_dot_ham.jpeg
  #
  # For details regarding assets in packages, see
  # https://flutter.dev/assets-and-images/#from-packages
  #
  # An image asset can refer to one or more resolution-specific "variants", see
  # https://flutter.dev/assets-and-images/#resolution-aware

  # To add custom fonts to your package, add a fonts section here,
  # in this "flutter" section. Each entry in this list should have a
  # "family" key with the font family name, and a "fonts" key with a
  # list giving the asset and other descriptors for the font. For
  # example:
  # fonts:
  #   - family: Schyler
  #     fonts:
  #       - asset: fonts/Schyler-Regular.ttf
  #       - asset: fonts/Schyler-Italic.ttf
  #         style: italic
  #   - family: Trajan Pro
  #     fonts:
  #       - asset: fonts/TrajanPro.ttf
  #       - asset: fonts/TrajanPro_Bold.ttf
  #         weight: 700
  #
  # For details regarding fonts in packages, see
  # https://flutter.dev/custom-fonts/#from-packages

README.md

html 复制代码
<!--
This README describes the package. If you publish this package to pub.dev,
this README's contents appear on the landing page for your package.

For information about how to write a good package README, see the guide for
[writing package pages](https://dart.dev/guides/libraries/writing-package-pages).

For general information about developing packages, see the Dart guide for
[creating packages](https://dart.dev/guides/libraries/create-library-packages)
and the Flutter guide for
[developing packages and plugins](https://flutter.dev/developing-packages).
-->

TODO: Put a short description of the package here that helps potential users
know whether this package might be useful for them.

## Features

TODO: List what your package can do. Maybe include images, gifs, or videos.

## Getting started

TODO: List prerequisites and provide or point to information on how to
start using the package.

## Usage

TODO: Include short and useful examples for package users. Add longer examples
to `/example` folder.

```dart
const like = 'sample';
```

## Additional information

TODO: Tell users more about the package: where to find more information, how to
contribute to the package, how to file issues, what response they can expect
from the package authors, and more.

二、配置pubspec.yaml

pubspec.yaml 文件是 Dart 和 Flutter 项目的核心配置文件,用于管理项目的依赖、版本、元数据等。

具体解释参见另一文:[Flutter]配置pubspec.yaml-CSDN博客

三、开发

1.是否需要使用library 指令?

我们创建的package项目文件中,默认文件中有使用如下的library指令。下面介绍一下,这个指令到底是否必要?

Dart 复制代码
library my_private_package;

在 Flutter 或 Dart 的包开发中,关于使用 library 指令的需要并不是强制性的,而是可选的。在很多情况下,特别是在现代 Flutter 开发实践中,通常不需要显式地使用 library 指令。下面是一些关于何时以及如何使用 library 指令的指导:

(1).不使用 library 指令

对于大多数 Flutter 应用和包,你实际上不需要使用 library 指令。每个 Dart 文件默认都是一个库,即使没有显式声明。你可以直接在文件中定义类、函数和其他顶级声明,而不需要首先声明一个库。

(2).使用场景

library 指令主要用于以下几个特定场景:

  • 文档生成 :如果你希望为整个库提供文档注释,那么可以使用 library 指令来定义一个库,并在它之前添加文档注释。
  • 部分指令 :如果你需要将一个库分割成多个部分文件,你可以使用 librarypart 指令。这种情况下,主文件应该有一个 library 指令,而其他文件则使用 part of 指令。但是,这种做法在 Flutter 中较少使用,因为 importexport 通常更加方便和灵活。

示例

假设你正在创建一个包含多个部分的库,你可能会这样做:

Dart 复制代码
// lib/my_private_package.dart
library my_private_package;

part 'src/part1.dart';
part 'src/part2.dart';

// lib/src/part1.dart
part of my_private_package;

// lib/src/part2.dart
part of my_private_package;

(3).现代 Flutter 开发建议

在现代 Flutter 开发中,推荐使用 importexport 来组织和重用代码,而不是使用 librarypart。这样做的好处包括更好的封装性、更清晰的依赖管理和避免命名空间问题。

2.自定义组件

进入这个包的目录,开发你需要的功能。例如,你可以在lib目录中添加Flutter widgets、类等。

示例,创建一个的自定义组件。

Dart 复制代码
import 'package:flutter/material.dart';

class GATagetView extends StatelessWidget {
  const GATagetView({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: Colors.red, // 页面的背景颜色
        resizeToAvoidBottomInset: false, // 防止键盘弹出时推动背景内容向上移动
        appBar: AppBar(
                backgroundColor: Colors.blue, // 导航栏的背景颜色
                iconTheme: const IconThemeData(
                  color: Colors.white, // 导航栏返回按钮颜色
                ),
                title: const Text(
                  "Taget",
                  style: TextStyle(
                    fontSize: 21,
                    fontWeight: FontWeight.bold,
                    color: Colors.white, // 导航栏标题文字颜色
                  ),
                ),
              ),
        body: Container(
          decoration: const BoxDecoration(
            color: Colors.white,
            // image: DecorationImage(
            //   image: AssetImage(Assets.images.iconBg.path),
            //   fit: BoxFit.cover, // 使图片铺满整个屏幕
            // ),
          ),
          child: SizedBox(
        width: double.infinity,
        height: double.infinity,
        child: SingleChildScrollView(
          child: Padding(
            padding: const EdgeInsets.all(10),
            child: Text(
              termsOfUseText(),
              textAlign: TextAlign.left,
              style: const TextStyle(
                color: Colors.black,
                fontSize: 14.0,
                fontWeight: FontWeight.normal,
                decoration: TextDecoration.none,
              ),
            ),
          ),
        ),
        ),
      )
    );
  }

  String termsOfUseText() {
    String str = """Terms of Use
    ......
    """;
    return str;
  }
}

四、测试

在 Flutter 开发中,创建和测试自定义组件是一个常见的需求。当开发私有包时,尤其是包含自定义组件的包,你会希望能够实时预览和调试这些组件。以下是一些有效的方法来预览和调试 Flutter 中的自定义组件:

1.使用示例应用

最常见的方法是在同一个项目中创建一个示例应用。这种方法很直接,也很易于设置:

  • 创建标准的 Flutter 应用 :cd到你的包的根目录,创建一个 example 文件夹,并在这个文件夹中初始化一个新的 Flutter 应用(使用 flutter create example 命令)。
bash 复制代码
$ flutter create example
  • 依赖本地包 :在示例应用的 pubspec.yaml 中添加对本地包的依赖。例如:
Dart 复制代码
dependencies:
  my_private_package:
    path: ../
  • 使用自定义组件:在示例应用中,你可以直接使用自定义包中的组件,然后运行示例应用来预览和调试这些组件。

实例:

Dart 复制代码
import 'package:my_private_package/ga_taget_view.dart';

TextButton(onPressed: (){
  Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) {
    return const GATagetView();
  }));
}, child: const Text("跳转", style: TextStyle(color: Colors.blue),))

2.使用 Hot Reload

利用 Flutter 的 Hot Reload 功能,你可以在进行代码更改后迅速看到效果,这对于调试和迭代开发非常有用。只需在示例应用中运行你的组件,每次更改后都可以立即看到更新。

3.使用 DartPad

如果组件不依赖于任何特定的第三方包或项目特定的设置,你可以使用 DartPad 在线预览和测试 Flutter 组件。DartPad 是一个在线的 Dart 和 Flutter 编辑器,支持即时预览。

4.单元测试和组件测试

详细介绍参考:https://blog.csdn.net/wsyx768/article/details/138487007

除了视觉预览,确保组件的功能和性能符合预期是非常重要的。你可以写单元测试和组件测试(widget tests)来验证组件的行为:

  • 单元测试:测试小块的代码逻辑。

  • 组件测试 :测试 Flutter 组件的 UI 行为。使用 testWidgets 函数来模拟用户交互和检查 UI 输出。

Dart 复制代码
import 'package:flutter_test/flutter_test.dart';
import 'package:my_custom_package/my_custom_widget.dart';

void main() {
  testWidgets('My Custom Widget Test', (WidgetTester tester) async {
    await tester.pumpWidget(MyCustomWidget());

    // 进行各种断言和交互
    expect(find.text('Some Text'), findsOneWidget);
  });
}

5.使用可视化调试工具

官方使用文档:https://docs.flutter.dev/tools/devtools

仓库地址:https://github.com/flutter/devtools

版本记录:https://docs.flutter.dev/tools/devtools/release-notes

使用 Flutter 的 DevTools 进行调试。DevTools 提供了性能视图、小部件检查器、内存和网络分析工具等,可以帮助你更深入地了解你的组件和应用的运行情况。

Flutter DevTools 是一个强大的调试工具套件,它帮助开发者理解和优化他们的 Flutter 应用。DevTools 提供了多个工具来调查布局问题、性能瓶颈、内存泄漏等。以下是如何使用 Flutter DevTools 进行调试的详细步骤:

(1).启动 DevTools

首先,确保你已经安装了 Flutter 和 Dart 插件。可以通过以下步骤启动 DevTools:

Open DevTools in Web Browser:

(2).DevTools 的主要功能

DevTools 包括多个工具,每个工具都专注于不同的调试方面:

A.Inspector(检查器)
  • 用途:检查和可视化 UI 布局和树状结构。
  • 功能:可以选择任何 widget 并查看其详细属性。这对于理解和调试布局问题非常有用。
B.Timeline(时间线)
  • 用途:分析应用的帧率和性能。
  • 功能:记录并查看应用的 UI 和 GPU 线程的时间线,帮助识别帧延迟的原因。
C.Memory(内存)
  • 用途:监控和分析应用的内存使用情况。
  • 功能:查看内存图表,并进行内存快照,可以帮助找到内存泄漏。
D.Network(网络)
  • 用途:监视应用中的 HTTP 请求。
  • 功能:记录和查看发送的请求,包括请求和响应的详情,非常适合调试网络问题。
E.Performance(性能)
  • 用途:更深入地分析应用性能。
  • 功能:提供 CPU 分析器和性能图表,帮助识别热点函数和性能瓶颈。
F.Debugger(调试器)
  • 用途:逐行执行代码。
  • 功能:设置断点,查看调用堆栈,执行代码。
G.Logging(日志)
  • 用途:查看应用产生的各种日志。
  • 功能:显示 print 输出、框架日志、垃圾回收日志等。

(3).使用 DevTools 进行调试

  • 连接应用:启动 DevTools 后,你需要将其连接到正在运行的 Flutter 应用。如果是通过命令行启动,通常需要在 DevTools 的浏览器界面中输入你的应用的 URI。
  • 选择工具:根据你的调试需求,选择相应的 DevTools 工具。
  • 交互和分析:使用 DevTools 提供的功能进行交互,收集并分析数据,根据分析结果调整和优化你的代码。

五、发布

你可以选择以下几种方式来发布你的包

1.私有Git仓库

  • 将你的包推送到一个私有的Git仓库(例如GitHub, GitLab, Bitbucket等)。
  • 确保你的pubspec.yaml文件里没有敏感信息。

2.本地路径

  • 对于局部或者仅在特定项目中使用,你可以通过本地路径来依赖包。
Dart 复制代码
dependencies:
  my_private_package:
    path: ../my_private_package

3.私有Pub服务器

  • 你可以搭建一个私有的Pub服务器,但这需要额外的配置和服务器管理。

4.发布成为公开的包

发布一个公开的 Flutter 或 Dart 包主要涉及将其发布到 Dart 的包管理系统 ------ pub.dev。这是 Dart 和 Flutter 社区的中央包仓库,类似于 Node.js 的 npm 或 Python 的 PyPI。下面是发布公开包的基本步骤:

(1).准备你的包

首先,确保你的包满足以下基本要求:

  • pubspec.yaml: 包含所有必要信息,如版本号、描述、依赖等。
  • README.md: 描述包的用途、安装方法、如何使用等。
  • CHANGELOG.md: 记录包的每个版本的变更。
  • LICENSE: 包含开源许可证的文件(例如 MIT、BSD、Apache 等)。

确保代码质量良好,有适当的注释和文档,同时最好有单元测试。

(2).检查包的健康状况

使用 Dart 的 pub 工具来分析你的包,确保没有警告或错误:

Dart 复制代码
$ dart pub publish --dry-run

这个命令会执行一个预发布检查,不会真正发布包,但会告诉你是否有什么问题需要解决。

使用publish命令时,需要先将publish_to配置移除。

Dart 复制代码
name: flutter_test_application
description: "A new Flutter project."

# 以下行可防止包被意外发布到
# pub.dev 使用 `flutter pub publish`。 这是私有包的首选。
publish_to: 'none' # 如果您想发布到 pub.dev,请删除此行

(3).发布包

一旦你的包准备好并通过了预检,你可以使用以下命令来发布它:

Dart 复制代码
$ dart pub publish

在执行这个命令时,将会要求你登录到你的 Google 账户(如果还没有登录的话),因为 pub.dev 使用 Google 账户进行身份验证。

(4).管理和维护

一旦你的包发布到 pub.dev,你需要对它进行管理和维护。这包括处理用户的问题、修复 bug、更新文档和发布新版本。

确保遵循语义版本控制规则更新你的包版本。当你做出修改并希望发布新版本时,你需要更新 pubspec.yaml 文件中的版本号,更新 CHANGELOG.md 文件,然后再次运行 dart pub publish

六、在项目中使用你的包

在其他Flutter项目中,你可以通过以下方式之一添加依赖:

1.Git依赖

pubspec.yaml中添加依赖后,运行**$ flutter pub get**来安装包。

php 复制代码
dependencies:
  my_private_package:
    git:
      url: git@github.com:yourusername/my_private_package.git
      ref: master
      # ref: v1.0.0
      # ref: abc1234

这种方式是从一个 Git 仓库导入依赖,ref 参数可以是一个分支名、标签或者具体的提交哈希。

版本管理

  • 分支名 : 指定为 master,意味着每次 pub getflutter pub get 都会检查 master 分支的最新状态。
  • 标签 : 如果你想管理版本,最佳实践是使用 Git 标签。你可以在 Git 仓库中为每个稳定版本创建一个标签,然后在 ref 中指定这个标签。
  • 提交哈希: 对于最精确的版本控制,你可以指定一个具体的提交哈希。这确保了无论何时拉取代码,依赖都是完全相同的。

使用实例:

Dart 复制代码
import 'package:my_private_package/ga_taget_view.dart';

TextButton(onPressed: (){
  Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) {
    return const GATagetView();
  }));
}, child: const Text("跳转", style: TextStyle(color: Colors.blue),))

2.路径依赖(如果包在本地)

在项目的pubspec.yaml中添加了依赖,运行**$ flutter pub get**来安装包。

(1).使用绝对路径

你需要根据你的系统环境确定完整的路径。例如,如果你的用户目录是 /Users/yourusername,则配置应如下所示:

Dart 复制代码
dependencies:
  my_private_package:
    path: /Users/yourusername/documents/my_private_package

(2).使用相对路径

如果你的私有包位于与你的 Flutter 项目相对较近的位置,你也可以使用相对路径。例如,如果你的 Flutter 项目和 my_private_package 都在同一个父目录下,你可以这样配置:

Dart 复制代码
dependencies:
  my_private_package:
    path: ../my_private_package

注意: 不能使用~/documents/my_private_package这种格式来指代目录。虽然 ~ 在许多命令行环境中通用(指代用户的主目录),但在 pubspec.yaml 文件中,Flutter 不解析 ~ 为主目录。

之后,你就可以在你的Flutter应用中导入并使用这个包了。

Dart 复制代码
import 'package:my_private_package/ga_taget_view.dart';

TextButton(onPressed: (){
  Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) {
    return const GATagetView();
  }));
}, child: const Text("跳转", style: TextStyle(color: Colors.blue),))
相关推荐
江上清风山间明月21 小时前
Flutter开发的应用页面非常多时如何高效管理路由
android·flutter·路由·页面管理·routes·ongenerateroute
Zsnoin能1 天前
flutter国际化、主题配置、视频播放器UI、扫码功能、水波纹问题
flutter
早起的年轻人1 天前
Flutter CupertinoNavigationBar iOS 风格导航栏的组件
flutter·ios
HappyAcmen1 天前
关于Flutter前端面试题及其答案解析
前端·flutter
coooliang2 天前
Flutter 中的单例模式
javascript·flutter·单例模式
coooliang2 天前
Flutter项目中设置安卓启动页
android·flutter
JIngles1232 天前
flutter将utf-8编码的字节序列转换为中英文字符串
java·javascript·flutter
B.-2 天前
在 Flutter 中实现文件读写
开发语言·学习·flutter·android studio·xcode
freflying11192 天前
使用jenkins构建Android+Flutter项目依赖自动升级带来兼容性问题及Jenkins构建速度慢问题解决
android·flutter·jenkins
机器瓦力2 天前
Flutter应用开发:对象存储管理图片
flutter