HarmonyOS Next 实战卡片开辟 02

打印 上一主题 下一主题

主题 1865|帖子 1865|积分 5599

HarmonyOS Next 实战卡片开辟 02

卡片开辟中,还有一个难点是体现图片。其中分为体现本舆图片和体现网络图片
体现本舆图片

卡片可以体现本舆图片,如存放在应用临时目次下的图片。路径比如
   /data/app/el2/100/base/你的项目boundleName/temp/123.png
  以下操作是为了得到一张 该目次下的图片做的准备工作

  • 截图,得到一张相册图片
  • 使用PhotoViewPicker来选择要操作的图片
  • 复制该图片到应用的临时目次下
  • 传递给卡片组件

截图,得到一张相册图片

使用PhotoViewPicker来选择要操作的图片

在首页中,选择要操作的图片,获得该文件的uri地址
   entry/src/main/ets/pages/Index.ets
  1. import { photoAccessHelper } from '@kit.MediaLibraryKit';
  2. import { fileIo } from '@kit.CoreFileKit';
  3. import { promptAction } from '@kit.ArkUI';
  4. @Entry
  5. @Component
  6. struct Index {
  7.   async aboutToAppear() {
  8.     // 创建一个新的 PhotoSelectOptions 实例来配置图片选择器的行为
  9.     let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
  10.     // 设置 MIME 类型为图像类型,这样用户只能选择图像文件
  11.     PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
  12.     // 设置用户可以选择的最大图片数量为 1 张
  13.     PhotoSelectOptions.maxSelectNumber = 1;
  14.     // 创建一个新的 PhotoViewPicker 实例,用于打开图片选择器
  15.     let photoPicker = new photoAccessHelper.PhotoViewPicker();
  16.     // 使用前面配置好的选项打开图片选择器,并等待用户完成选择
  17.     // 注意这里的 select 方法是一个异步方法,所以需要使用 await 关键字等待其结果
  18.     const PhotoSelectResult = await photoPicker.select(PhotoSelectOptions);
  19.     // 获取用户选择的第一张图片的 URI(统一资源标识符)
  20.     // 假设这里只关心用户选择的第一张图片
  21.     // uri file://media/Photo/3/IMG_1729864738_002/screenshot_20241025_215718.jpg
  22.     const uri = PhotoSelectResult.photoUris[0];
  23.     promptAction.showToast({ message: `${uri}` })
  24.   }
  25.   build() {
  26.     RelativeContainer() {
  27.     }
  28.     .height('100%')
  29.     .width('100%')
  30.   }
  31. }
复制代码

复制该图片到应用的临时目次下

目标是将刚才的图片复制到应用的临时目次下,为最后的卡片体现本舆图片做准备

在刚才的代码下,接着实现
  1.     // 获取应用的临时目录
  2.     let tempDir = getContext(this).getApplicationContext().tempDir;
  3.     // 生成一个新的文件名
  4.     const fileName = 123 + '.png'
  5.     // 通过缓存路径+文件名 拼接出完整的路径
  6.     const copyFilePath = tempDir + '/' + fileName
  7.     // 将文件 拷贝到 临时目录
  8.     const file = fileIo.openSync(uri, fileIo.OpenMode.READ_ONLY)
  9.     fileIo.copyFileSync(file.fd, copyFilePath)
复制代码
传递给卡片组件

在当前的环节中,有一个需要特别需要留意的地方,就是构造符合的数据。比如以下的数据

然后在创建卡片的时候,在Ability中读取图片地址,拼接参数,传递给卡片
   entry/src/main/ets/entryformability/EntryFormAbility.ets
  1. import { Want } from '@kit.AbilityKit';
  2. import { fileIo } from '@kit.CoreFileKit';
  3. import { formBindingData, FormExtensionAbility } from '@kit.FormKit';
  4. export default class EntryFormAbility extends FormExtensionAbility {
  5.   // 在添加卡片时,打开一个本地图片并将图片内容传递给卡片页面显示
  6.   onAddForm(want: Want): formBindingData.FormBindingData {
  7.     // 假设在当前卡片应用的tmp目录下有一个本地图片 123.png
  8.     let tempDir = this.context.getApplicationContext().tempDir;
  9.     let imgMap: Record<string, number> = {};
  10.     // 打开本地图片并获取其打开后的fd
  11.     let file = fileIo.openSync(tempDir + '/' + '123.png');
  12.     imgMap['imgBear'] = file.fd;
  13.     class FormDataClass {
  14.       // 卡片需要显示图片场景, 必须和下列字段formImages 中的key 'imgBear' 相同。
  15.       imgName: string = 'imgBear';
  16.       // 卡片需要显示图片场景, 必填字段(formImages 不可缺省或改名), 'imgBear' 对应 fd
  17.       formImages: Record<string, number> = imgMap;
  18.     }
  19.     let formData = new FormDataClass();
  20.     console.log("formDataformData", JSON.stringify(formData))
  21.     // 将fd封装在formData中并返回至卡片页面
  22.     return formBindingData.createFormBindingData(formData);
  23.   }
  24. }
复制代码

卡片需要 使用 'memory://+this.imgName'  来体现图片
  
  1. let storageWidgetImageUpdate = new LocalStorage();
  2. @Entry(storageWidgetImageUpdate)
  3. @Component
  4. struct WidgetImageUpdateCard {
  5.   @LocalStorageProp('imgName') imgName: ResourceStr = "";
  6.   build() {
  7.     Column() {
  8.     }
  9.     .width('100%').height('100%')
  10.     .backgroundImage('memory://' + this.imgName)
  11.     .backgroundImageSize(ImageSize.Cover)
  12.   }
  13. }
复制代码
完整效果

小结


  • 截图,得到一张相册图片
  • 使用PhotoViewPicker来选择要操作的图片
  • 复制该图片到应用的临时目次下
  • 传递给卡片组件
以上的前三步调都是为了得到临时图片,实际开辟中根据情况来获取即可
还有


  • Image组件通过入参(memory://fileName)中的(memory://)标识来举行远端内存图片体现,其中fileName需要和EntryFormAbility传递对象(‘formImages’: {key: fd})中的key相对应。
  • Image组件通过传入的参数是否有变化来决定是否刷新图片,因此EntryFormAbility每次传递过来的imgName都需要不同,连续传递两个类似的imgName时,图片不会刷新。
  • 在卡片上展示的图片,巨细需要控制在2MB以内。
体现网络图片

卡片中不支持直接体现网络图片如以下方式是不支持的
  1. Image("https://cn-assets.gitee.com/assets/mini_app-e5eee5a21c552b69ae6bf2cf87406b59.jpg")
复制代码
我们需要申请网络权限,然后将图片下载下来,最后再重复类似卡片体现本舆图片的步调即可

  • 申请网络权限
           entry/src/main/module.json5
       

  • 设置网络图片地址
  • 使用http开始下载
  • 写入文件
  • 返回给卡片组件
   entry/src/main/ets/entryformability/EntryFormAbility.ets
  1. import { Want } from '@kit.AbilityKit';
  2. import { fileIo } from '@kit.CoreFileKit';
  3. import { formBindingData, FormExtensionAbility, formInfo, formProvider } from '@kit.FormKit';
  4. import { http } from '@kit.NetworkKit';
  5. import { BusinessError } from '@kit.BasicServicesKit';
  6. export default class EntryFormAbility extends FormExtensionAbility {
  7.   // 在添加卡片时,打开一个本地图片并将图片内容传递给卡片页面显示
  8.   onAddForm(want: Want) {
  9.     // 注意:FormExtensionAbility在触发生命周期回调时被拉起,仅能在后台存在5秒
  10.     // 建议下载能快速下载完成的小文件,如在5秒内未下载完成,则此次网络图片无法刷新至卡片页面上
  11.     const formId = want.parameters![formInfo.FormParam.IDENTITY_KEY] as string
  12.     let netFile =
  13.       'https://env-00jxhf99mujs.normal.cloudstatic.cn/card/3.webp?expire_at=1729871552&er_sign=0eb3f6ac3730703039b1565b6d3e59ad'; // 需要在此处使用真实的网络图片下载链接
  14.     let httpRequest = http.createHttp()
  15.     // 下载图片
  16.     httpRequest.request(netFile)
  17.       .then(async (data) => {
  18.         if (data?.responseCode == http.ResponseCode.OK) {
  19.           // 拼接图片地址
  20.           let tempDir = this.context.getApplicationContext().tempDir;
  21.           let fileName = 'file' + Date.now();
  22.           let tmpFile = tempDir + '/' + fileName;
  23.           let imgMap: Record<string, number> = {};
  24.           class FormDataClass {
  25.             // 卡片需要显示图片场景, 必须和下列字段formImages 中的key fileName 相同。
  26.             imgName: string = fileName;
  27.             // 卡片需要显示图片场景, 必填字段(formImages 不可缺省或改名), fileName 对应 fd
  28.             formImages: Record<string, number> = imgMap;
  29.           }
  30.           // 打开文件
  31.           let imgFile = fileIo.openSync(tmpFile, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
  32.           imgMap[fileName] = imgFile.fd;
  33.           // 写入文件
  34.           await fileIo.write(imgFile.fd, data.result as ArrayBuffer);
  35.           let formData = new FormDataClass();
  36.           let formInfo = formBindingData.createFormBindingData(formData);
  37.           // 下载完网络图片后,再传递给卡片
  38.           formProvider.updateForm(formId, formInfo)
  39.           fileIo.closeSync(imgFile);
  40.           httpRequest.destroy();
  41.           console.log("============")
  42.         }
  43.       })
  44.       .catch((e: BusinessError) => {
  45.         console.log("eeee", e.message)
  46.       })
  47.     class FormData {
  48.       formId: string = ""
  49.     }
  50.     // 先返回基本数据
  51.     return formBindingData.createFormBindingData(new FormData);
  52.   }
  53.   onFormEvent(formId: string, message: string): void {
  54.   }
  55. }
复制代码

作者

作者:万少
链接:https://www.nutpi.net/
來源:坚果派 著作权归作者全部。
商业转载请接洽作者获得授权,非商业转载请注明出处。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

王國慶

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表