在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
指令来定义一个库,并在它之前添加文档注释。 - 部分指令 :如果你需要将一个库分割成多个部分文件,你可以使用
library
和part
指令。这种情况下,主文件应该有一个library
指令,而其他文件则使用part of
指令。但是,这种做法在 Flutter 中较少使用,因为import
和export
通常更加方便和灵活。
示例
假设你正在创建一个包含多个部分的库,你可能会这样做:
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 开发中,推荐使用 import
和 export
来组织和重用代码,而不是使用 library
和 part
。这样做的好处包括更好的封装性、更清晰的依赖管理和避免命名空间问题。
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:
-
启动你的应用:使用命令行或者你的 IDE 启动 Flutter 应用。
-
检查 DevTools 版本: 在命令行中,可以通过运行 $ dart devtools --version 检查您当前的 DevTools 版本。
-
从 Android Studio 运行 DevTools: https://docs.flutter.dev/tools/devtools/android-studio
-
从命令行运行 DevTools: https://docs.flutter.dev/tools/devtools/cli
-
从 VS Code 运行 DevTools: https://docs.flutter.dev/tools/devtools/vscode
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 get
或flutter 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),))