赵走x博客
网站访问量:151910
首页
书籍
软件
工具
古诗词
搜索
登录
75、插件开发:iOS端API实现
64、文件操作
85、图片加载原理与缓存
84、Flutter运行机制-从启动到显示
83、RenderObject和RenderBox
82、Element与BuildContext
81、Flutter UI系统
80、国际化常见问题
79、使用Intl包
78、实现Localizations
77、让App支持多语言
76、Texture和PlatformView
73、开发Flutter插件
72、插件开发:平台通道简介
71、开发Package
70、Json转Dart Model类
69、使用Socket API
68、使用WebSockets
67、实例:Http分块下载
66、Http请求-Dio http库
65、通过HttpClient发起HTTP请求
63、自绘实例:圆形背景渐变进度条
62、自绘组件 (CustomPaint与Canvas)
61、组合实例:TurnBox
60、组合现有组件
59、自定义组件方法简介
58、动画过渡组件
57、通用"切换动画"组件(AnimatedSwitcher)
56、交织动画
55、Hero动画
54、自定义路由切换动画
53、动画基本结构及状态监听
51、动画
50、通知(Notification)
49、全局事件总线
48、手势识别
47、原始指针事件处理
46、事件处理与通知
45、对话框详解
44、异步UI更新(FutureBuilder、StreamBuilder)
43、颜色和主题
42、跨组件状态共享(Provider)
41、数据共享(InheritedWidget)
40、导航返回拦截(WillPopScope)
39、功能型Widget简介
38、滚动监听及控制
37、CustomScrollView
36、GridView
35、ListView
34、SingleChildScrollView
33、可滚动组件简介
32、剪裁(Clip)
31、Scaffold、TabBar、底部导航
30、Container
29、变换(Transform)
28、装饰容器DecoratedBox
27、尺寸限制类容器
26、填充(Padding)
25、容器类Widget
24、对齐与相对定位(Align)
23、层叠布局 Stack、Positioned
22、流式布局
21、弹性布局(Flex)
20、线性布局(Row和Column)
19、布局类组件简介
18、进度指示器
17、输入框及表单
16、单选开关和复选框
15、图片及ICON
14、按钮
13、文本、字体样式
12、状态管理
11、Widget简介
10、Flutter异常捕获
9、调试Flutter应用
8、资源管理
7、包管理
6、路由管理
5、第一个Flutter应该:计数器应用示例
4、Dart语言简介
3、搭建Flutter开发环境
2、初识Flutter
1、移动开发技术简介
71、开发Package
资源编号:76225
Flutter实战
书籍
热度:116
第二章中已经讲过如何使用Package(包),我们知道通过package可以创建共享的模块化代码,本节将重点讲一下如何开发并发布我们自己的Package。
第二章中已经讲过如何使用Package(包),我们知道通过package可以创建共享的模块化代码,本节将重点讲一下如何开发并发布我们自己的Package。一个最小的Package包括: * 一个pubspec.yaml文件:声明了Package的名称、版本、作者等的元数据文件。 * 一个 lib 文件夹:包括包中公开的(public)代码,最少应有一个
.dart文件 Flutter Packages分为两类: * Dart包:其中一些可能包含Flutter的特定功能,因此对Flutter框架具有依赖性,这种包仅用于Flutter,例如fluro包。 * 插件包:一种专用的Dart包,其中包含用Dart代码编写的API,以及针对Android(使用Java或Kotlin)和针对iOS(使用OC或Swift)平台的特定实现,也就是说插件包括原生代码,一个具体的例子是battery插件包。 注意,虽然Flutter的Dart运行时和Dart VM运行时不是完全相同,但是如果Package中没有涉及这些存在差异的部分,那么这样的包可以同时支持Flutter和Dart VM,如Dart http网络库dio。 下面我将带领读者一步步来开发一个Dart Package。 # 第一步:创建Dart包 您可以通过Android Studio:File>New>New Flutter Project 来创建一个Package工程,如图12-1所示:  您也可以通过使用--template=package 来执行 flutter create 命令来创建: ``` flutter create --template=package hello ``` 这将在hello/文件夹下创建一个具有以下专用内容的package工程: * lib/hello.dart:Package的Dart代码 * test/hello_test.dart:Package的单元测试代码。 # 实现package 对于纯Dart包,只需在主lib/
.dart文件内或lib目录中的文件中添加功能即可 。要测试软件包,请在test目录中添加unit tests。下面我们看看如何组织Package包的代码,我们以shelf Package为例,它的目录结构如图12-2所示:  在lib根目录下的“shelf.dart”中,导出了多个“lib/src”目录下的dart文件: ``` export 'src/cascade.dart'; export 'src/handler.dart'; export 'src/handlers/logger.dart'; export 'src/hijack_exception.dart'; export 'src/middleware.dart'; export 'src/pipeline.dart'; export 'src/request.dart'; export 'src/response.dart'; export 'src/server.dart'; export 'src/server_handler.dart'; ``` 而Package中主要的功能的源码都在src目录下。shelf Package也导出了一个迷你库: shelf_io,它主要是处理HttpRequest的。 # 导入包 当需要使用这个Package时,我们可以通过"package:"指令来指定包的入口文件: ``` import 'package:utilities/utilities.dart'; ``` 同一个包中的源码文件之间也可以使用相对路径来导入。 # 生成文档 可以使用 dartdoc 工具来为Package生成文档,开发者需要做的就是遵守文档注释语法在代码中添加文档注释,最后使用dartdoc可以直接生成API文档(一个静态网站)。文档注释是使用三斜线"///"开始,如: ``` /// The event handler responsible for updating the badge in the UI. void updateBadge() { ... } ``` 详细的文档语法请参考dartdoc 。 # 处理包的相互依赖 如果我们正在开发一个hello包,它依赖于另一个包,则需要将该依赖包添加到pubspec.yaml文件的dependencies部分。 下面的代码使url_launcher插件的API在hello包中是可用的: 在 hello/pubspec.yaml中: ``` dependencies: url_launcher: ^0.4.2 ``` 现在可以在hello中import 'package:url_launcher/url_launcher.dart' 然后调用 launch()方法了。 这与在Flutter应用程序或任何其他Dart项目中引用软件包没有什么不同。 但是,如果hello碰巧是一个插件包,其平台特定的代码需要访问url_launcher公开的特定于平台的API,那么我们还需要为特定于平台的构建文件添加合适的依赖声明,如下所示。 ### Android 在 hello/android/build.gradle: ``` android { // lines skipped dependencies { provided rootProject.findProject(":url_launcher") } } ``` 您现在可以在hello/android/src源码中import io.flutter.plugins.urllauncher.UrlLauncherPlugin访问UrlLauncherPlugin类。 ### iOS 在hello/ios/hello.podspec: ``` Pod::Spec.new do |s| # lines skipped s.dependency 'url_launcher' ``` 您现在可以在hello/ios/Classes源码中 #import "UrlLauncherPlugin.h" 然后访问 UrlLauncherPlugin类。 # 解决依赖冲突 假设我们想在我们的hello包中使用some_package和other_package,并且这两个包都依赖url_launcher,但是依赖的是url_launcher的不同的版本。 那我们就有潜在的冲突。避免这种情况的最好方法是在指定依赖关系时,程序包作者使用版本范围而不是特定版本。 ``` dependencies: url_launcher: ^0.4.2 # 这样会较好, 任何0.4.x(x >= 2)都可. image_picker: '0.1.1' # 不是很好,只有0.1.1版本. ``` 如果some_package声明了上面的依赖关系,other_package声明了url_launcher版本像’0.4.5’或’^0.4.0’,pub将能够自动解决问题。 即使some_package和other_package声明了不兼容的url_launcher版本,它仍然可能会和url_launcher以兼容的方式正常工作。 你可以通过向hello包的pubspec.yaml文件中添加依赖性覆盖声明来处理冲突,从而强制使用特定版本: 强制使用 0.4.3版本的url_launcher,在 hello/pubspec.yaml中: ``` dependencies: some_package: other_package: dependency_overrides: url_launcher: '0.4.3' ``` 如果冲突的依赖不是一个包,而是一个特定于Android的库,比如guava,那么必须将依赖重写声明添加到Gradle构建逻辑中。 强制使用23.0版本的guava库,在hello/android/build.gradle中: ``` configurations.all { resolutionStrategy { force 'com.google.guava:guava:23.0-android' } } ``` Cocoapods目前不提供依赖覆盖功能。 # 发布Package 一旦实现了一个包,我们可以在Pub上发布它 ,这样其他开发者就可以轻松使用它。 在发布之前,检查pubspec.yaml、README.md以及CHANGELOG.md文件,以确保其内容的完整性和正确性。然后,运行 dry-run 命令以查看是否都准备OK了: ``` flutter packages pub publish --dry-run ``` 验证无误后,我们就可以运行发布命令了: ``` flutter packages pub publish ``` 如果你遇到包发布失败的情况,先检查是否因为众所周知的网络原因,如果是网络问题,可以使用VPN,这里需要注意的是一些代理只会代理部分APP的网络请求,如浏览器的,它们可能并不能代理dart的网络请求,所以在这种情况下,即使开了代理也依然无法连接到Pub,因此,在发布Pub包时使用全局代理或全局VPN会保险些。如果网络没有问题,以管理员权限(sudo)运行发布命令重试。 很多时候开启全局代理也不会让terminal中的流量打代理服务器走,以socks5为例,应该在终端下输入以下指令: ``` export all_proxy=socks5://127.0.0.1:1080 ``` 此时终端中的http和https流量会打代理服务器走,可以通过curl -i https://ip.cn指令查看代理设置是否成功。