三方库基本使用
1.如何获取三方库
目前提供了两种途径获取开源三方库:
● Gitee三方库资源汇总:https://gitee.com/openharmony-tpc/tpc_resource
● OpenHarmony三方库中心仓:https://ohpm.openharmony.cn
2. 常用三方库介绍
常用的三方库可以分为UI、动画、网络、图片、多媒体、数据存储、安全、工具等。
● UI库:
○ @ohos/textlayoutbuilder:可以定制任一样式的文本构建工具,包括字体间距、大小、颜色、富文本高亮显示等。
○ @ohos/roundedimageview:可以生成圆角矩形、或者椭圆形等图片形状。
● 网络库:
○ @ohos/axios:可以运行在node.js 和浏览器中,基于Axios 原库v1.3.4版本进行适配,并沿用其现有用法和特性。
● 动画库:
○ @ohos/lottie:可以解析Adobe After Effects软件通过Bodymovin插件导出的json格式的动画,并在移动设备上进行本地渲染。
○ @ohos/svg:可以解析SVG图片并渲染到页面上。
三方库在系统能力的基础上,提供了更加方便的使用,在许多场景下,能够极大提升开发者的开发效率。
3. 下载命令行工具
请前往下载中心获取并下载命令行工具Command Line Tools。 根据系统需要下载对应的命令行工具,我这里用的是Mac(ARM)版本。
4. 配置命令行工具
下载好了命令行工具(Command Line Tools)之后,需要将其配置到系统环境变量下;
4.1 Windows系统配置
- 解压 command-line-tools 压缩包找到其bin目录
- 将command-line-tools/bin目录配置到环境变量中
4.2 Mac系统配置
- 将下载后的命令行工具解压到本地。
- 打开终端工具,执行以下命令,根据输出结果分别执行不同命令。
echo $SHELL
echo命令执行完之后,结果可能是/bin/bash 或者 /bin/zsh,表示当前你的系统使用的是哪个配置文件。
- 如果输出结果为/bin/bash,则执行以下命令,打开.bash_profile文件。
vi ~/.bash_profile
- 如果输出结果为/bin/zsh,则执行以下命令,打开.zshrc文件。
vi ~/.zshrc
- 单击字母“i”,进入Insert模式。输入以下内容,在PATH路径下添加环境变量。
export PATH=~/command-line-tools/bin:$PATH
- 编辑完成后,单击Esc键,退出编辑模式,然后输入“:wq”,单击Enter键保存
- 执行以下命令,使配置的环境变量生效。
- 如果步骤a时打开的是.bash_profile文件,请执行如下命令:
source ~/.bash_profile
- 如果步骤a时打开的是.zshrc文件,请执行如下命令:
source ~/.zshrc
5.使用三方库@ohos/lottie
5.1 什么是@ohos/lottie
@ohos/lottie是基于lottie-web开发,集成在三方库社区内的开源版本,是HarmonyOS系统中复杂动画的一种解决方案。
动画是传达想法和创造更好的用户交互体验的工具,常见使用动画的场景如下:
● 启动动画:APP logo动画的播放。
● 加载动画:网络请求的loading动画。
● 上下拉刷新动画:请求更多资源时的刷新动画。
● 按钮动画:切换按钮、编辑按钮、播放按钮等按钮的切换过渡动画。
● 视图转场动画:一些场景的转场添加动画能够提升用户体验。
@ohos/lottie提供了使用JSON动画文件的解决方案,开发者可以在原生应用中像使用静态图像一样使用动画,而不用关注动画的实现过程,并且@ohos/lottie具有一套完整的API控制动画的行为,可以让动画更具有交互性。接下来将介绍@ohos/lottie的安装和基本使用。
5.2 @ohos/lottie的安装与卸载
● 安装@ohos/lottie
通过ohpm执行对应的指令,将lottie安装到项目中(建议在项目的模块根目录下安装)。
ohpm install @ohos/lottie
安装完成后,在模块根目录下的oh-packagejson5文件中可以找到@ohos/lottie的配置信息;在
oh_modules/@ohos目录中找到lottie包的存放位置。
- 卸载@ohos/lottie通过ohpm执行卸载指令,将lottie从项目中删除,其程序包和配置信息将会从项目中移除。
ohpm uninstall @ohos/lottie
5.3 使用@ohos/lottie
5.3.1 @ohos/lottie 使用步骤
● @ohos/lottie的引入
通过import指令在项目中引入@ohos/lottie到文件中。
import lottie from '@ohos/lottie'
● 构建Canvas画布
@ohos/lottie解析JSON动画文件的数据需要基于Canvas 画布进行2D渲染,所以在加载JSON动画之前,要先初始化渲染上下文,并在画面中创建Canvas画布区域,将对应的渲染上下文renderingContext传递给Canvas。
// 初始化渲染上下文
private renderingSettings: RenderingContextSettings = new RenderingContextSettings(true) // 设置开启抗锯齿
private renderingContext: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.renderingSettings) // 创建2D渲染上下文
// 加载Canvas画布
Canvas(this.renderingContext)
...
● 使用@ohos/lottie加载JSON动画
加载JSON动画需要用到loadAnimation方法,在方法中需配置相应的初始设置,包括渲染上下文、渲染方式以及JSON动画资源的路径等。可以直接使用lottie.loadAnimation方法,也可以用一个animationItem实例来接收返回的animationItem对象。
// 用animationItem实例接收
let animationItem = lottie.loadAnimation({
container: this.renderingContext, // 渲染上下文
renderer: 'canvas', // 渲染方式
loop: true, // 是否循环播放,默认true
autoplay: true, // 是否自动播放,默认true
path: 'common/lottie/data.json', // json路径
})
lottie.loadAnimation({ // 或者直接使用
container: this.renderingContext, // 渲染上下文
renderer: 'canvas', // 渲染方式
loop: true, // 是否循环播放,默认true
autoplay: true, // 是否自动播放,默认true
path: 'common/lottie/data.json', // json路径
})
● @ohos/lottie控制动画
@ohos/lottie内封装了包括状态控制,进度控制,播放设置控制和属性控制等多个API,用户可以利用这些API完成对动画的控制,实现更加灵活的交互效果。
// 播放、暂停、停止、销毁 可以使用lottie,也可以使用animationItem实例进行控制
lottie.play(); // 从目前停止的帧开始播放
lottie.stop(); // 停止播放,回到第0帧
lottie.pause(); // 暂停该动画,在当前帧停止并保持
lottie.togglePause(); // 切换暂停/播放状态
lottie.destroy(); // 删除该动画,移除相应的元素标签等。在unmount的时候,需要调用该方法
// 播放进度控制
animationItem.goToAndStop(value, isFrame); // 跳到某个时刻/帧并停止。isFrame(默认false)指示value表示帧还是时间(毫秒)
animationItem.goToAndPlay(value, isFrame); // 跳到某个时刻/帧并进行播放
animationItem.goToAndStop(30, true); // 例:跳转到第30帧并停止
animationItem.goToAndPlay(300); // 例:跳转到第300毫秒并播放
// 控制帧播放
animationItem.setSegment(5,15); // 限定动画资源播放时的整体帧范围,即设置动画片段
animationItem.resetSegments(5,15); // 重置播放的动画片段
animationItem.playSegments(arr, forceFlag); // arr可以包含两个数字或者两个数字组成的数组,forceFlag表示是否立即强制播放该片段
animationItem.playSegments([10,20], false); // 例:播放完之前的片段,播放10-20帧
animationItem.playSegments([[5,15],[20,30]], true); //例: 直接播放5-15帧和20-30帧
// 动画基本属性控制
lottie.setSpeed(speed); // 设置播放速度,speed为1表示正常速度
lottie.setDirection(direction); // 设置播放方向,1表示正向播放,-1表示反向播放
// 获取动画帧数属性
animationItem.getDuration(); //获取动画时长
5.3.2 @ohos/lottie 应用案例
import lottie, { AnimationItem } from '@ohos/lottie';
@Entry
@Component
export struct Index {
private renderingSettings: RenderingContextSettings = new RenderingContextSettings(true);
private renderingContext: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.renderingSettings);
private animateName: string = 'data';
private animateItem: AnimationItem | null = null;
@State canvasTitle: string = '';
aboutToDisappear(): void {
lottie.destroy();
}
onPageShow(): void {
lottie.play();
}
onPageHide(): void {
lottie.pause();
}
build() {
Flex({
direction: FlexDirection.Column,
justifyContent: FlexAlign.SpaceBetween
}) {
// Canvas area
Column() {
Canvas(this.renderingContext)
.width('100%')
.aspectRatio(1.76)
.backgroundImage($r('app.media.canvasBg'))
.backgroundImageSize(ImageSize.Cover)
.onDisAppear(() => {
lottie.destroy(this.animateName);
})
Text(this.canvasTitle)
.width('100%')
.fontSize(14)
.textAlign(TextAlign.Center)
.fontWeight(FontWeight.Bold)
.fontColor('#182431')
.margin({ top: 12 })
.opacity(0.4)
}
.margin({
top: 10,
left: 10,
right: 10
})
// Buttons area
Column({ space: 12 }) {
Button() {
Text('动画加载')
.fontSize(16)
.fontColor('#007dff')
.fontWeight(FontWeight.Bold)
}
.width('100%')
.height(40)
.backgroundColor('#dedbdb')
.onClick(() => {
if (this.animateItem !== null) {
this.animateItem.destroy();
this.animateItem = null;
}
this.canvasTitle = '加载动画';
this.animateItem = lottie.loadAnimation({
container: this.renderingContext,
renderer: 'canvas',
loop: 10,
autoplay: true,
name: this.animateName,
path: 'lottie/data.json'
});
})
Button() {
Text('结束并回到第0帧')
.fontSize(16)
.fontColor('#007dff')
.fontWeight(FontWeight.Bold)
}
.width('100%')
.height(40)
.backgroundColor('#dedbdb')
.onClick(() => {
if (this.animateItem === null) {
return;
}
this.canvasTitle = '结束并回到第0帧'
this.animateItem.goToAndPlay(0, true);
})
Flex({ justifyContent: FlexAlign.SpaceBetween }) {
Button() {
Text('播放')
.fontSize(16)
.fontColor('#007dff')
.fontWeight(FontWeight.Bold)
}
.width('49%')
.height(40)
.backgroundColor('#dedbdb')
.onClick(() => {
if (this.animateItem === null) {
return;
}
this.canvasTitle = '播放';
lottie.play();
})
Button() {
Text('暂停')
.fontSize(16)
.fontColor('#007dff')
.fontWeight(FontWeight.Bold)
}
.width('49%')
.height(40)
.backgroundColor('#dedbdb')
.onClick(() => {
if (this.animateItem === null) {
return;
}
this.canvasTitle = '暂停';
lottie.pause();
})
}
}
.padding({
left: 23,
right: 23,
bottom: 41
})
}
.height('100%')
}
}
6.使用第三方库@ohos/axios
6.1 axios简介
Axios ,是一个基于 promise 的网络请求库,可以运行 node.js 和浏览器中。本库基于Axios 原库v1.3.4版本进行适配,使其可以运行在 OpenHarmony,并沿用其现有用法和特性。
● http 请求
● Promise API
● request 和 response 拦截器
● 转换 request 和 response 的 data 数据
● 自动转换 JSON data 数据
6.2 下载安装axios
ohpm install @ohos/axios
6.3 申请权限
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
}
}
6.4 导入@ohos/axios模块
import axios from '@ohos/axios'
6.5 axios快速入门
axios支持泛型参数,由于ArkTS不再支持any类型,需指定参数的具体类型。
如:axios<T, R = AxiosResponse, D>(url)
● T: 是响应数据类型。当发送一个 POST 请求时,客户端可能会收到一个 JSON 对象。T 就是这个 JSON 对象的类型。
● R: 是响应体的类型。当服务器返回一个响应时,响应体通常是一个 JSON 对象。R 就是这个 JSON 对象的类型。默认情况下,R 是 AxiosResponse,这意味着响应体是一个 AxiosResponse 对象,它的 data 属性是 T 类型的
● D: 是请求体的参数类型(data的类型)。当发送一个 GET 请求时,可能会在 URL 中添加一些查询参数。参数为空情况下,D 是 null类型。
6.5.1 数据模型
interface Student {
id?: number
name: string
phoneNumber: string
birthdate: string
chineseScore: number
mathScore: number
englishScore: number
hobbies: string
createTime?: string
updateTime?: string
}
6.5.2 配置方式发起请求
- 发起get请求
axios<string, AxiosResponse<string>, null>({
url: 'http://10.0.2.2:8080/student/get',
method: "get",
params: {
id: 1
}
}).then((res: AxiosResponse<string>) => {
this.result = JSON.stringify(res.data)
})
- 发起post请求
axios<string, AxiosResponse<string>, Student>({
url: 'http://10.0.2.2:8080/student/add',
method: "post",
data:{
name: 'HarmonyOS Next',
chineseScore: 99,
mathScore: 99,
englishScore: 99,
birthdate: '1991-10-10',
phoneNumber: '10100659988',
hobbies: '运动,唱歌,阅读'
}
}).then((res: AxiosResponse<string>) => {
this.result = JSON.stringify(res.data)
})
6.5.3 别名方式发起请求
- 发送一个get请求
axios.get<string, AxiosResponse<string>, number>('http://10.0.2.2:8080/student/get', {
params: {
id: 3
}
}).then((res: AxiosResponse<string>) => {
console.info('result:' + JSON.stringify(res.data));
}).catch((error:AxiosError) => {
console.info(JSON.stringify(error))
})
- 发送一个post请求
axios.post<string, AxiosResponse<string>, Student>("http://10.0.2.2:8080/student/add",{
name:'dd',
chineseScore:80,
mathScore:99,
englishScore:100,
birthdate:'2020-10-10',
phoneNumber:'10100659988',
hobbies:'运动,唱歌,阅读'
}).then((res: AxiosResponse<string>) => {
console.info('result:' + JSON.stringify(res.data));
}).catch((error:AxiosError) => {
console.info(JSON.stringify(error))
})
- 发送put请求
axios.put<string, AxiosResponse<string>, Student>("http://10.0.2.2:8080/student/update/condition", {
id: 6,
name: 'HarmonyOS',
chineseScore: 100,
mathScore: 100,
englishScore: 100,
phoneNumber: '13100659988',
birthdate: '1991-10-10',
hobbies: '吃饭,睡觉,打游戏'
}).then((res: AxiosResponse<string>) => {
console.info('result:' + JSON.stringify(res.data));
}).catch((error: AxiosError) => {
console.info('error:' + JSON.stringify(error))
})
- 发送delete请求
axios.delete<string, AxiosResponse<string>, number[]>("http://10.0.2.2:8080/student/delete", {
params: {
ids: '1,2,3'
}
}).then((res: AxiosResponse<string>) => {
console.info('result:' + JSON.stringify(res.data));
}).catch((error: AxiosError) => {
console.info('error:' + JSON.stringify(error))
})
6.6 上传文件
- 上传图片:将/resources/rawfile/a.png图片上传到服务器
//1.获取文件呢绒
let byteArray = getContext(this).resourceManager.getRawFileContentSync('a.png')
//2.创建表单数据
let formData = new FormData()
//3.发送请求
formData.append("file", byteArray.buffer,{filename:'a.png'})
axios.post<string, AxiosResponse<string>, FormData>('http://10.0.2.2:8080/common/upload', formData, {
headers: { 'Content-Type': 'multipart/form-data' },
context: getContext(this),
onUploadProgress: (progressEvent: AxiosProgressEvent): void => {
console.info(progressEvent && progressEvent.loaded && progressEvent.total ?
Math.ceil(progressEvent.loaded / progressEvent.total * 100) + '%' : '0%');
},
}).then((res: AxiosResponse) => {
console.info("result" + JSON.stringify(res.data));
}).catch((error: AxiosError) => {
console.error("error:" + JSON.stringify(error));
})
- 上传文件
let formData = new FormData()
let cacheDir = getContext(this).cacheDir
try {
// 写入
let path = cacheDir + '/hello.txt';
let file = fs.openSync(path, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE)
fs.writeSync(file.fd, "hello, world"); // 以同步方法将数据写入文件
fs.fsyncSync(file.fd); // 以同步方法同步文件数据。
fs.closeSync(file.fd);
// 读取
let file2 = fs.openSync(path, 0o2);
let stat = fs.lstatSync(path);
let buf2 = new ArrayBuffer(stat.size);
fs.readSync(file2.fd, buf2); // 以同步方法从流文件读取数据。
fs.fsyncSync(file2.fd);
fs.closeSync(file2.fd);
formData.append('file', buf2);
// formData.append('file', buf2, { filename: 'text.txt', type: 'text/plain'}); 设置多部分表单数据的数据名称和数据类型类型
} catch (err) {
console.info('err:' + JSON.stringify(err));
}
// 发送请求
axios.post<string, AxiosResponse<string>, FormData>('http://10.0.2.2:8080/common/upload', formData, {
headers: { 'Content-Type': 'multipart/form-data' },
context: getContext(this),
onUploadProgress: (progressEvent: AxiosProgressEvent): void => {
console.info(progressEvent && progressEvent.loaded && progressEvent.total ? Math.ceil(progressEvent.loaded / progressEvent.total * 100) + '%' : '0%');
},
}).then((res: AxiosResponse) => {
console.info("result" + JSON.stringify(res.data));
}).catch((error: AxiosError) => {
console.error("error:" + JSON.stringify(error));
})