
回复
当用户在浏览壁纸时,点击壁纸,便进入到详情页面,详情页面提供了壁纸下载的功能,这里主要就是讲解壁纸下载的实现过程
这里的壁纸渲染是封装了一个自定义组件来实现的
WallpaperCard
组件内,封装了个骨架屏组件,当图片还没有加载出来时,就优先显示骨架屏。
import { NavigationConst } from "../const/NavigationConst"
import { NavigationUtils } from "../utils/NavigationUtils"
import { PixabayImage } from "../utils/types"
import { IvSkeleton } from "./IvSkeleton"
// 壁纸卡片组件
@ComponentV2
export struct WallpaperCard {
@Param @Require image: PixabayImage
// 图片加载状态
@Local isLoading: boolean = true
build() {
Column() {
Image(this.image.webformatURL)
.width('100%')
.height(300)
.borderRadius(10)
.visibility(this.isLoading ? Visibility.Hidden : Visibility.Visible)
.onComplete(() => {
// 图片加载完成
this.isLoading = false
})
.onClick(() => {
// 打开图片详情
NavigationUtils.getInstance().navigatePush(NavigationConst.ImageDetail_View, this.image)
})
// 骨架屏占位
if (this.isLoading) {
IvSkeleton({ widthValue: '100%', heightValue: 300 })
.borderRadius(10)
.position({ x: 0, y: 0 })
}
}
.width('100%')
}
}
当点击壁纸时,便跳转到壁纸详情页面
NavigationUtils.getInstance().navigatePush(NavigationConst.ImageDetail_View, this.image)
这里的跳转是使用了Navigation
进行路由管理的,所以不懂怎么使用的小伙伴需要先学习下。
壁纸详情的布局挺简单,上到下直接布局即可。
核心业务在于 下载壁纸,这里的下载壁纸分成三个核心步骤,分别是 申请壁纸下载权限和下载壁纸、保存到相册。
这里申请壁纸下载权限使用的是鸿蒙提供的安全按钮 SaveButton,安全控件的保存控件。用户点击保存控件,应用可以临时获取存储权限,而不需要权限弹框授权确认。
SaveButton属性
名称 | 类型 | 必填 | 说明 |
---|---|---|---|
icon | SaveIconStyle | 否 | 设置保存控件的图标风格。不传入该参数表示没有图标。 |
text | SaveDescription | 否 | 设置保存控件的文本描述。不传入该参数表示没有文字描述。 |
buttonType | ButtonType | 否 | 设置保存控件的背景样式。不传入该参数,系统默认提供Capsule类型按钮。 |
loadImageWithUrl
自己封装的方法用来下载对应的图片
SaveButton(
{
text: SaveDescription.SAVE_IMAGE
}
)
.width(120)
.height(40)
.backgroundColor($r('sys.color.brand'))
.borderRadius(20)
.fontColor($r('sys.color.comp_background_list_card'))
.onClick(async () => {
await loadImageWithUrl(this.selectedImage!.largeImageURL)
promptAction.showToast({ message: `下载成功` })
})
下载图片主要使用 http模块来实现
// 将 http 请求封装为返回 Promise 的函数
const httpRequest = (url: string) => {
return new Promise<http.HttpResponse>((resolve, reject) => {
http.createHttp().request(url, {
method: http.RequestMethod.GET,
connectTimeout: 60000,
readTimeout: 60000
}, (error: BusinessError, data: http.HttpResponse) => {
if (error) {
reject(error);
} else {
resolve(data);
}
});
});
};
url
,表示要请求的URL。http.createHttp()
创建一个HTTP客户端实例。request
方法发送HTTP GET请求到指定的URL,并设置请求的超时时间为60秒。reject
函数,将错误传递给Promise的拒绝处理程序。resolve
函数,将HTTP响应传递给Promise的解析处理程序。核心代码是利用了 image
和 photoAccessHelper
kit。
主要逻辑:
httpRequest
函数发起HTTP请求,获取图片数据。responseCode.OK
),如果是,则继续处理。ImageSource
对象。ImageSource
对象创建PixelMap
对象,该对象表示图片的像素数据。ImagePacker
对象将PixelMap
对象打包为数据。PixelMap
对象。export const loadImageWithUrl = async (url: string) => {
let responseCode = http.ResponseCode;
let imagePackerApi = image.createImagePacker();
let packOpts: image.PackingOption = { format: 'image/jpeg', quality: 98 };
// 发起 http 请求
const OutData = await httpRequest(url);
let code: http.ResponseCode | number = OutData.responseCode;
if (responseCode.OK === code) {
let imageData: ArrayBuffer = OutData.result as ArrayBuffer;
let imageSource: image.ImageSource = image.createImageSource(imageData);
class tmp {
height: number = 100;
width: number = 100;
}
let options: Record<string, number | boolean | tmp> = {
'alphaType': 0, // 透明度
'editable': false, // 是否可编辑
'pixelFormat': 3, // 像素格式
'scaleMode': 1, // 缩略值
'size': { height: 100, width: 100 }
}; // 创建图片大小
// 创建像素图
const pixelMap: PixelMap = await imageSource.createPixelMap(options);
// 打包像素图为数据
const buffer = await imagePackerApi.packToData(pixelMap, packOpts);
const context = getContext();
let helper = photoAccessHelper.getPhotoAccessHelper(context);
let uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'png');
let file = await fileIo.open(uri, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
// 写入文件
await fileIo.write(file.fd, buffer);
// 关闭文件
await fileIo.close(file.fd);
// 释放像素图
pixelMap.release();
}
}
获取资料的途径,可以关注我们 官网的公众号 青蓝逐码 ,输入 项目名称 《自然壁纸》 即可获得以上资料。
如果你兴趣想要了解更多的鸿蒙应用开发细节和最新资讯,甚至你想要做出一款属于自己的应用!欢迎在评论区留言或者私信或者看我个人信息,可以加入技术交流群。