Flutter-Package插件的开发、发布、使用
创建Package
参数说明:
- 要创建纯 Dart 库的 package,使用带有
--template=package
标志的flutter create
命令
flutter create --template=plugin 'plugin_name'
创建完成后,可以看到这个里面是不包含原生代码的,没有以前的 iOS 和 Android 目录
发布 Package
完善 package 里面的代码,我这里只是简单写了一个自定义Dialog
的代码,然后别人引用我这个包,使用这个自定义的升级 Dialog 。写完代码后,这个时候就开始上传 package 了。具体的 package 包的代码在文章最后面。
pubspec.yaml
里的参数说明:
name:包的名称
description: 包的描述信息
version:包的版本,假如上传了example,这里必须>=1.0.0
homepage:网页介绍,需要填写一个能正常访问的地址
CHANGELOG.md
里面也要改成对应的版本号
先检查Dart包
进入 package_dialog_demo
包项目的目录,然后执行
flutter packages pub publish --dry-run
假如包有问题是可以检测出来的。这里明显可以看到是没有问题的
发布 Dart 包
flutter packages pub publish
常见问题:
- 询问是否要发布
0.0.1
版本的包
- 输入y,然后回车。提示让去谷歌的这个地址进行验证,所以首先要保证有一个
Google 邮箱
账号
- 拷贝这个地址,在浏览器输入,然后登陆 Google 账号,验证完成
只要在浏览器验证完成,终端自动也会提示验证完成
之后会长时间卡住,最后失败了
- 这个时候会报错,看着是网络问题,需要翻墙,并且需要在终端设置代理
指定服务器进行发布
flutter packages pub publish --server=https://pub.dartlang.org
- 解决完上个问题,发现又出现下面许可证的问题
解决这个问题,就需要在GitHub
上面创建仓库,选择对应的许可证
然后创建好仓库后,进入仓库看到多了一个这个文件
打开这个文件,把内容拷贝,粘贴到 package 包 LICENSE
的里面
再次检查,看是否有问题,没有问题再次执行上传操作
这样就成功的创建包并且上传成功了,这个时候去 pub.dev/ 搜索上传的包 package_dialog_demo
,发现是有的
使用 Package
创建使用工程
创建一个工程flutter_custom_dialog
,引入这个自定义的package包,看是否能成功使用
引入 package 包
package_dialog_demo: ^0.0.1
然后pub get, 在工程里面引入,我这里设置了别名DialogDemo
防止冲突,就可以正常的使用了
import 'package:package_dialog_demo/package_dialog_demo.dart' as DialogDemo;
包中使用图片的问题
注意: 虽然能正常使用,但是发现package里面有个图片不能正常显示。这个时候就需要去添加图片,由于我们包上传只显示lib
文件夹,所以在这个里面创建一个images
文件夹放需要显示的图片
再次更新版本号0.0.2
,然后执行上传。并且需要在使用你包的工程里面具体路径的引入,不然就会报图片找不到
这样再次更下了0.0.2
的包后,运行工程发现图片使用正常的
其实封装的包里面包含图片使用非常不方便,别人使用你的库还需要引入你使用的具体图片路径,不然就无法正常显示。其实更建议少用图片,或者在包里暴露出传图片的属性。
优化 Package
这个时候看我们上传的包,只有100分,满分有130分,需要增加对应的包描述60-80字,并且需要增加一个示例Demo
增加Example
我们可以使用上面创建的flutter_custom_dialog
工程代码,在包里面创建一个example
文件,把main.dart代码拷贝到这里。然后依旧在终端检查包有没有问题,没有问题开始执行上传操作,这个时候示例代码就被传上去了,并且还是空安全
的。
这里的评分只有110分,一个是描述需要配置,一个是API的个数不够,这两个填写完就可以达到130分了。
增加功能模块
在平常的开发中,我们看其他人开发的包也可以看出,并不想把所有的文件的内容爆露出来,而只是爆露出对应的使用,实现的过程是看不到的。
- 我这里重新创建了一个文件
custom_dialog.dart
文件,在里面实现对应功能,然后爆露给package_dialog_demo.dart
part of 'package_dialog_demo.dart';
- 在
package_dialog_demo.dart
中导入,一些其他文件需要导入的文件只需要在这里导入就可以了
part 'custom_dialog.dart';
Package 包里面的代码
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
//定义枚举类型
enum DialogType { upgrade, alert }
class CustomDialog extends Dialog {
final String? title; //标题
final String? content; //内容
final DialogType? dialogType;
final void Function()? cancelCallBack;
final void Function()? confirmCallBack;
CustomDialog(
{this.title,
this.content,
this.dialogType,
this.confirmCallBack,
this.cancelCallBack});
@override
Widget build(BuildContext context) {
switch (this.dialogType) {
case DialogType.upgrade:
return Material(
type: MaterialType.transparency,
child: Center(
child: upgradeDialog(context),
),
);
break;
case DialogType.alert:
return Material(
type: MaterialType.transparency,
child: Center(
child: customAlertDialog(context),
),
);
break;
default:
return Material(
type: MaterialType.transparency,
child: Center(
child: upgradeDialog(context),
),
);
}
}
Widget customAlertDialog(BuildContext context) {
return Container(
height: 300,
margin: EdgeInsets.only(left: 40, right: 40),
color: Colors.white,
child: Column(
children: [
Padding(
padding: EdgeInsets.all(20),
child: Stack(
children: [
Align(
child: Text(
title!,
style: TextStyle(fontSize: 20, color: Color(0xFF2D2D2D)),
),
),
Align(
alignment: Alignment.centerRight,
child: InkWell(
child: Icon(Icons.close),
onTap: () {
Navigator.of(context).pop();
},
),
),
],
),
),
Divider(),
Container(
width: double.infinity,
margin: EdgeInsets.all(10),
child: Text(
content!,
textAlign: TextAlign.left,
),
)
],
),
);
}
Widget upgradeDialog(BuildContext context) {
return Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
margin: EdgeInsets.only(left: 20, right: 20),
decoration: const ShapeDecoration(
color: Color(0xfff2f2f2),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(10),
),
),
),
child: Column(
children: [
Container(
height: 250,
decoration: const BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10)),
image: DecorationImage(
image: AssetImage('images/head_icon.png'),
fit: BoxFit.cover,
)),
),
SizedBox(
height: 20,
),
Container(
padding: EdgeInsets.only(left: 10, right: 10),
width: double.infinity,
child: const Text(
'本次更新',
style: TextStyle(
fontSize: 20,
color: Color(0xFF2D2D2D),
decoration: TextDecoration.none),
textAlign: TextAlign.left,
),
),
SizedBox(
height: 15,
),
Container(
padding: EdgeInsets.only(left: 10, right: 10),
width: double.infinity,
child: Text(
'解决了一些已知问题',
style: TextStyle(
fontSize: 16,
color: Color(0xFF333333),
decoration: TextDecoration.none),
textAlign: TextAlign.left,
),
),
SizedBox(
height: 20,
),
Divider(),
Container(
height: 40,
margin: EdgeInsets.only(bottom: 15),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
this.confirmCallBack!();
},
child: Text(
'升级',
style: TextStyle(fontSize: 18),
),
),
VerticalDivider(
color: Colors.grey,
width: 1,
),
TextButton(
onPressed: () {
Navigator.of(context).pop();
this.cancelCallBack!();
},
child: Text('暂不升级', style: TextStyle(fontSize: 18))),
],
),
)
],
),
)
],
),
);
}
}
参考文章:flutterchina.club/developing-…
欢迎关注、点赞及转发。
转载自:https://juejin.cn/post/7038143571890798605