HarmonyOS Next 实战卡片开辟 02
卡片开辟中,还有一个难点是体现图片。其中分为体现本舆图片和体现网络图片
体现本舆图片
卡片可以体现本舆图片,如存放在应用临时目次下的图片。路径比如
/data/app/el2/100/base/你的项目boundleName/temp/123.png
以下操作是为了得到一张 该目次下的图片做的准备工作
- 截图,得到一张相册图片
- 使用PhotoViewPicker来选择要操作的图片
- 复制该图片到应用的临时目次下
- 传递给卡片组件
截图,得到一张相册图片
使用PhotoViewPicker来选择要操作的图片
在首页中,选择要操作的图片,获得该文件的uri地址
entry/src/main/ets/pages/Index.ets
- import { photoAccessHelper } from '@kit.MediaLibraryKit';
- import { fileIo } from '@kit.CoreFileKit';
- import { promptAction } from '@kit.ArkUI';
- @Entry
- @Component
- struct Index {
- async aboutToAppear() {
- // 创建一个新的 PhotoSelectOptions 实例来配置图片选择器的行为
- let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
- // 设置 MIME 类型为图像类型,这样用户只能选择图像文件
- PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
- // 设置用户可以选择的最大图片数量为 1 张
- PhotoSelectOptions.maxSelectNumber = 1;
- // 创建一个新的 PhotoViewPicker 实例,用于打开图片选择器
- let photoPicker = new photoAccessHelper.PhotoViewPicker();
- // 使用前面配置好的选项打开图片选择器,并等待用户完成选择
- // 注意这里的 select 方法是一个异步方法,所以需要使用 await 关键字等待其结果
- const PhotoSelectResult = await photoPicker.select(PhotoSelectOptions);
- // 获取用户选择的第一张图片的 URI(统一资源标识符)
- // 假设这里只关心用户选择的第一张图片
- // uri file://media/Photo/3/IMG_1729864738_002/screenshot_20241025_215718.jpg
- const uri = PhotoSelectResult.photoUris[0];
- promptAction.showToast({ message: `${uri}` })
- }
- build() {
- RelativeContainer() {
- }
- .height('100%')
- .width('100%')
- }
- }
复制代码 复制该图片到应用的临时目次下
目标是将刚才的图片复制到应用的临时目次下,为最后的卡片体现本舆图片做准备
在刚才的代码下,接着实现
- // 获取应用的临时目录
- let tempDir = getContext(this).getApplicationContext().tempDir;
- // 生成一个新的文件名
- const fileName = 123 + '.png'
- // 通过缓存路径+文件名 拼接出完整的路径
- const copyFilePath = tempDir + '/' + fileName
- // 将文件 拷贝到 临时目录
- const file = fileIo.openSync(uri, fileIo.OpenMode.READ_ONLY)
- fileIo.copyFileSync(file.fd, copyFilePath)
复制代码 传递给卡片组件
在当前的环节中,有一个需要特别需要留意的地方,就是构造符合的数据。比如以下的数据
然后在创建卡片的时候,在Ability中读取图片地址,拼接参数,传递给卡片
entry/src/main/ets/entryformability/EntryFormAbility.ets
- import { Want } from '@kit.AbilityKit';
- import { fileIo } from '@kit.CoreFileKit';
- import { formBindingData, FormExtensionAbility } from '@kit.FormKit';
- export default class EntryFormAbility extends FormExtensionAbility {
- // 在添加卡片时,打开一个本地图片并将图片内容传递给卡片页面显示
- onAddForm(want: Want): formBindingData.FormBindingData {
- // 假设在当前卡片应用的tmp目录下有一个本地图片 123.png
- let tempDir = this.context.getApplicationContext().tempDir;
- let imgMap: Record<string, number> = {};
- // 打开本地图片并获取其打开后的fd
- let file = fileIo.openSync(tempDir + '/' + '123.png');
- imgMap['imgBear'] = file.fd;
- class FormDataClass {
- // 卡片需要显示图片场景, 必须和下列字段formImages 中的key 'imgBear' 相同。
- imgName: string = 'imgBear';
- // 卡片需要显示图片场景, 必填字段(formImages 不可缺省或改名), 'imgBear' 对应 fd
- formImages: Record<string, number> = imgMap;
- }
- let formData = new FormDataClass();
- console.log("formDataformData", JSON.stringify(formData))
- // 将fd封装在formData中并返回至卡片页面
- return formBindingData.createFormBindingData(formData);
- }
- }
复制代码 卡片需要 使用 'memory://+this.imgName' 来体现图片
- let storageWidgetImageUpdate = new LocalStorage();
- @Entry(storageWidgetImageUpdate)
- @Component
- struct WidgetImageUpdateCard {
- @LocalStorageProp('imgName') imgName: ResourceStr = "";
- build() {
- Column() {
- }
- .width('100%').height('100%')
- .backgroundImage('memory://' + this.imgName)
- .backgroundImageSize(ImageSize.Cover)
- }
- }
复制代码 完整效果
小结
- 截图,得到一张相册图片
- 使用PhotoViewPicker来选择要操作的图片
- 复制该图片到应用的临时目次下
- 传递给卡片组件
以上的前三步调都是为了得到临时图片,实际开辟中根据情况来获取即可
还有
- Image组件通过入参(memory://fileName)中的(memory://)标识来举行远端内存图片体现,其中fileName需要和EntryFormAbility传递对象(‘formImages’: {key: fd})中的key相对应。
- Image组件通过传入的参数是否有变化来决定是否刷新图片,因此EntryFormAbility每次传递过来的imgName都需要不同,连续传递两个类似的imgName时,图片不会刷新。
- 在卡片上展示的图片,巨细需要控制在2MB以内。
体现网络图片
卡片中不支持直接体现网络图片如以下方式是不支持的
- Image("https://cn-assets.gitee.com/assets/mini_app-e5eee5a21c552b69ae6bf2cf87406b59.jpg")
复制代码 我们需要申请网络权限,然后将图片下载下来,最后再重复类似卡片体现本舆图片的步调即可
- 申请网络权限
entry/src/main/module.json5
- 设置网络图片地址
- 使用http开始下载
- 写入文件
- 返回给卡片组件
entry/src/main/ets/entryformability/EntryFormAbility.ets
- import { Want } from '@kit.AbilityKit';
- import { fileIo } from '@kit.CoreFileKit';
- import { formBindingData, FormExtensionAbility, formInfo, formProvider } from '@kit.FormKit';
- import { http } from '@kit.NetworkKit';
- import { BusinessError } from '@kit.BasicServicesKit';
- export default class EntryFormAbility extends FormExtensionAbility {
- // 在添加卡片时,打开一个本地图片并将图片内容传递给卡片页面显示
- onAddForm(want: Want) {
- // 注意:FormExtensionAbility在触发生命周期回调时被拉起,仅能在后台存在5秒
- // 建议下载能快速下载完成的小文件,如在5秒内未下载完成,则此次网络图片无法刷新至卡片页面上
- const formId = want.parameters![formInfo.FormParam.IDENTITY_KEY] as string
- let netFile =
- 'https://env-00jxhf99mujs.normal.cloudstatic.cn/card/3.webp?expire_at=1729871552&er_sign=0eb3f6ac3730703039b1565b6d3e59ad'; // 需要在此处使用真实的网络图片下载链接
- let httpRequest = http.createHttp()
- // 下载图片
- httpRequest.request(netFile)
- .then(async (data) => {
- if (data?.responseCode == http.ResponseCode.OK) {
- // 拼接图片地址
- let tempDir = this.context.getApplicationContext().tempDir;
- let fileName = 'file' + Date.now();
- let tmpFile = tempDir + '/' + fileName;
- let imgMap: Record<string, number> = {};
- class FormDataClass {
- // 卡片需要显示图片场景, 必须和下列字段formImages 中的key fileName 相同。
- imgName: string = fileName;
- // 卡片需要显示图片场景, 必填字段(formImages 不可缺省或改名), fileName 对应 fd
- formImages: Record<string, number> = imgMap;
- }
- // 打开文件
- let imgFile = fileIo.openSync(tmpFile, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
- imgMap[fileName] = imgFile.fd;
- // 写入文件
- await fileIo.write(imgFile.fd, data.result as ArrayBuffer);
- let formData = new FormDataClass();
- let formInfo = formBindingData.createFormBindingData(formData);
- // 下载完网络图片后,再传递给卡片
- formProvider.updateForm(formId, formInfo)
- fileIo.closeSync(imgFile);
- httpRequest.destroy();
- console.log("============")
- }
- })
- .catch((e: BusinessError) => {
- console.log("eeee", e.message)
- })
- class FormData {
- formId: string = ""
- }
- // 先返回基本数据
- return formBindingData.createFormBindingData(new FormData);
- }
- onFormEvent(formId: string, message: string): void {
- }
- }
复制代码 作者
作者:万少
链接:https://www.nutpi.net/
來源:坚果派 著作权归作者全部。
商业转载请接洽作者获得授权,非商业转载请注明出处。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |