HarmonyOS Next 实战卡片开发 02

HarmonyOS Next 实战卡片开发 02

卡片开发中,还有一个难点是显示图片。其中分为显示本地图片和显示网络图片

显示本地图片

卡片可以显示本地图片,如存放在应用临时目录下的图片。路径比如

/data/app/el2/100/base/你的项目boundleName/temp/123.png

以下操作是为了得到一张 该目录下的图片做的准备工作

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

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

截图,得到一张相册图片

使用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.jpgconst uri = PhotoSelectResult.photoUris[0];promptAction.showToast({ message: `${uri}` })}build() {RelativeContainer() {}.height('100%').width('100%')}
}

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

目标是将刚才的图片复制到应用的临时目录下,为最后的卡片显示本地图片做准备

image-20241025220456712

在刚才的代码下,接着实现

    // 获取应用的临时目录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)

传递给卡片组件

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

image-20241025221558917

然后在创建卡片的时候,在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.pnglet tempDir = this.context.getApplicationContext().tempDir;let imgMap: Record<string, number> = {};// 打开本地图片并获取其打开后的fdlet file = fileIo.openSync(tempDir + '/' + '123.png');imgMap['imgBear'] = file.fd;class FormDataClass {// 卡片需要显示图片场景, 必须和下列字段formImages 中的key 'imgBear' 相同。imgName: string = 'imgBear';// 卡片需要显示图片场景, 必填字段(formImages 不可缺省或改名), 'imgBear' 对应 fdformImages: 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)}
}

完整效果

小结

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

以上的前三步骤都是为了得到临时图片,实际开发中根据情况来获取即可

还有

  • 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")

我们需要申请网络权限,然后将图片下载下来,最后再重复类似卡片显示本地图片的步骤即可

  1. 申请网络权限

    entry/src/main/module.json5

    image-20241025225743062

  2. 设置网络图片地址

  3. 使用http开始下载

  4. 写入文件

  5. 返回给卡片组件

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 stringlet 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 对应 fdformImages: 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/

來源:坚果派 著作权归作者所有。

商业转载请联系作者获得授权,非商业转载请注明出处。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/59000.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++ 算法进阶】算法提升十一 十二

目录标题 让字符串成为回文串的最少插入次数题目题目分析代码题目题目 字符子串 &#xff08;滑动窗口&#xff09;题目题目分析代码 最长连续子序列 &#xff08;头尾表&#xff09;题目题目分析代码 让字符串成为回文串的最少插入次数 题目 本题为为LC原题 题目如下 题目分…

让redis一直开启服务/自动启动

文章目录 你的redis是怎么打开的黑窗不能关?必须要自动启动吗?再说说mysql 本文的所有指令都建议在管理员权限下打开cmd控制台 推荐的以管理员身份打开控制台的方式 Win R 打开运行 输入cmdShift Ctrl Enter 你的redis是怎么打开的 安装过redis的朋友都知道, redis的安…

域名邮箱推荐:安全与稳定的邮件域名邮箱!

域名邮箱推荐及绑定攻略&#xff1f;最好用的域名邮箱服务推荐&#xff1f; 域名邮箱&#xff0c;作为一种个性化且专业的电子邮件服务&#xff0c;越来越受到企业和个人的青睐。烽火将详细介绍域名邮箱登录的全过程&#xff0c;从注册到登录&#xff0c;帮助您轻松掌握这一重…

AI教育革命:个性化学习的新篇章

内容概要 在 教育 领域&#xff0c;人工智能 的崭露头角带来了前所未有的变化。如今&#xff0c;个性化学习 已不再是一个遥不可及的梦想&#xff0c;而是通过 AI 技术真正实现的可能。借助先进的数据分析能力&#xff0c;教师可以实时跟踪和评估每位学生的学习进度&#xff0…

[2024最新] macOS 发起 Bilibili 直播(不使用 OBS)

文章目录 1、B站账号 主播认证2、开启直播3、直播设置添加素材、隐私设置指定窗口添加/删除 窗口 4、其它说明官方直播帮助中心直播工具教程 目前搜到的 macOS 直播教程都比较古早&#xff0c;大部分都使用 OBS&#xff0c;一番探索下来&#xff0c;发现目前已经不需要 OBS了&a…

刷题---轮转数组

本题来自力扣刷题&#xff1a;轮转数组 首先我们来看一下题目描述 解题思路&#xff1a;首先创建一个新的数组&#xff0c;将后面k个数据数据放到新数组前面&#xff0c;将size-1个数据放在剩下的空间中&#xff0c;再把新数组的数据赋值给nums。看下图更好理解 代码展示 vo…

默认 iOS 设置使已锁定的 iPhone 容易受到攻击

苹果威胁研究的八个要点 苹果手机间谍软件问题日益严重 了解 Apple 苹果的设备和服务器基础模型发布 尽管人们普遍认为锁定的 iPhone 是安全的&#xff0c;但 iOS 中的默认设置可能会让用户面临严重的隐私和安全风险。 安全研究员 Lambros 通过Pen Test Partners透露&#…

常用的c++特性-->day02

c11新特性 可调用对象案例分析 可调用对象包装器语法案例可调用对象包装器作为函数参数补充&#xff1a;类型转换运算符案例 可调用对象绑定器语法格式绑定非类成员函数/变量案例1案例2案例3案例4 绑定类成员函数/变量 lambda表达式捕获列表案例1返回值案例2 --> 包装器绑定…

Linux进程信号(信号的产生)

目录 什么是信号&#xff1f; 信号的产生 信号产生方式1&#xff1a;键盘 前台进程 后台进程 查看信号 signal系统调用 案例 理解进程记录信号 软件层面 硬件层面 信号产生方式2:指令 信号产生方式3:系统调用 kill系统调用 案例 其他产生信号的函数调用 1.rais…

国产化浪潮下,高科技企业如何选择合适的国产ftp软件方案?

高科技企业在数字化转型和创新发展中&#xff0c;数据资产扮演着越来越重要的角色。在研发过程中产生的实验数据、设计文档、测试结果等&#xff0c;专利、商标、版权之类的创新成果等&#xff0c;随着信息量急剧增加和安全威胁的复杂化&#xff0c;传统的FTP软件已经不能满足这…

如何对接正规的外卖霸王餐接口?

根据搜索结果&#xff0c;合规地对接外卖霸王餐接口需要遵循以下步骤和注意事项&#xff1a; 1.合法性与合规性&#xff1a; 确保业务和对API的使用符合当地法律法规&#xff0c;包括消费者权益保护法、电子商务法等。了解并遵守与食品相关的法律法规&#xff0c;如食品安全法…

VUE3实现好看的通用网站源码模板

文章目录 1.设计来源1.1 网站主界面1.2 登录界面1.3 注册界面1.4 图文列表模板界面1.5 简洁列表模板界面1.6 文章内容左右侧模板界面1.7 文章内容模板界面 2.效果和源码2.1 动态效果2.2 源代码2.3 目录结构 源码下载万套模板&#xff0c;程序开发&#xff0c;在线开发&#xff…

论文阅读:DualDn Dual-domain Denoising via Differentiable ISP

这篇文章是 2024 ECCV 的一篇文章&#xff0c;介绍的是降噪相关的工作。 Abstract 图像去噪是相机图像信号处理 (ISP) 流程中的一个关键组成部分。将去噪器融入 ISP 流程有两种典型方式&#xff1a;直接对拍摄的原始帧&#xff08;RAW域&#xff09;应用去噪器&#xff0c;或…

从文本到图像:AIGC 如何改变内容生产的未来

从文本到图像&#xff1a;AIGC 如何改变内容生产的未来 在过去的几年里&#xff0c;人工智能生成内容&#xff08;AIGC&#xff09;技术迅速崛起&#xff0c;从基础的文本生成到更复杂的图像、音频甚至视频生成。如今&#xff0c;AIGC 已经不仅仅是技术研究中的一个概念&#…

运维智能化转型:AIOps引领IT运维新浪潮

1. AIOps是什么&#xff1f; AIOps&#xff08;Artificial Intelligence for IT Operations&#xff09;&#xff0c;即人工智能在IT运维中的应用&#xff0c;通过机器学习技术处理运维数据&#xff08;如日志、监控信息和应用数据&#xff09;&#xff0c;解决传统自动化运维…

Spring Boot 与 Vue 共筑航空机票预定卓越平台

作者介绍&#xff1a;✌️大厂全栈码农|毕设实战开发&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。 &#x1f345;获取源码联系方式请查看文末&#x1f345; 推荐订阅精彩专栏 &#x1f447;&#x1f3fb; 避免错过下次更新 Springboot项目精选实战案例 更多项目…

2024 第五次周赛

A: 直接遍历即可 #include<bits/stdc.h> using namespace std;typedef long long ll; typedef pair<ll, ll>PII; const int N 2e6 10; const int MOD 998244353; const int INF 0X3F3F3F3F;int n, m; int main() {cin >> n;int cnt 0;for(int i 0; i …

斐波那契数的第n个数代码分享(c基础)

1&#xff1a;迭代 //斐波那契数的第n个数 #include<stdio.h> //unsigned long long Fib(n) //{ // // if (1 n || 2 n) // return 1; // else return Fib((n - 1) Fib((n - 2); // // //} unsigned long long Fib(n) {if (n 1 || n 2)return 1;else{int j 3;u…

STM32单片机WIFI语音识别智能衣柜除湿消毒照明

实践制作DIY- GC0196-WIFI语音识别智能衣柜 一、功能说明&#xff1a; 基于STM32单片机设计-WIFI语音识别智能衣柜 二、功能介绍&#xff1a; STM32F103C系列最小系统板LCD1602显示器ULN2003控制的步进电机&#xff08;柜门开关&#xff09;5V加热片直流风扇紫外消毒灯DHT11…

qt QShortcut详解

1、概述 QShortcut是Qt框架中的一个类&#xff0c;它提供了一种创建键盘快捷键的方式。通过QShortcut&#xff0c;开发者可以将特定的键盘组合&#xff08;如CtrlC、AltF4等&#xff09;与应用程序中的动作&#xff08;如复制、关闭窗口等&#xff09;关联起来。当用户在应用程…