鸿蒙卡片开发保姆级教程

卡片

1. 卡片概念

  1. 什么是卡片?

    卡片用来显示或者提示一些基本信息或者进行一些基本操作。注意不能做重逻辑,所有重要逻辑全部交给应用

  2. 如果是元服务如何唤醒?

    因为元服务不提供桌面应用图标,我们可以通过用户手动的方式在桌面上添加一张卡片,通过点击卡片来唤起元服务。

2. 创建卡片

  1. 在编辑器中创建
    卡片创建步骤

  2. 选择动态卡片
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    卡片的特点:
    1.卡片只能承载少量的内容和交互
    2. 卡片可以充当元服务icon作为入口,默认提供一张服务卡片作为入口
    3. 普通应用也可以添加服务卡片,但默认没有添加卡片

    元服务和普通应用的区别
    在这里插入图片描述

  3. 添加卡片
    在这里插入图片描述
    在这里插入图片描述

3. ArkTS卡片实现原理

在这里插入图片描述

4. ArkTS卡片渲染服务运行原理

在这里插入图片描述

5. 卡片的服务通信

5.1 卡片-------> 应用
  • 使用postCardAction方法
  1. 在卡片pages中书写代码
// 卡片的应用
@Entry
@Component
struct WidgetCard {@State count: number = 10;build() {Column() {Row({ space: 20 }) {Button('++').onClick(() => {this.count++;postCardAction(this, {action: 'call',abilityName: 'EntryAbility',params: {method: 'updateFormCount',num: this.count}})})Text(this.count.toString()).fontSize(18)Button('--').onClick(() => {if (this.count > 0) {this.count--;postCardAction(this,{action:'call',abilityName: 'EntryAbility',params:{method:'updateFormCount',num:this.count}})}})}}.width('100%').height('100%').onClick(() => {// 点击唤醒应用postCardAction(this, {action: 'router',abilityName: 'EntryAbility'})})}
}
  1. module.json5添加-保持应用在后台权限
 "requestPermissions": [{"name": "ohos.permission.KEEP_BACKGROUND_RUNNING"}],
  1. 应用的entryability中进行接收
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
import { rpc } from '@kit.IPCKit';
import { JSON } from '@kit.ArkTS';
import { preferences } from '@kit.ArkData';
import { formBindingData, formProvider } from '@kit.FormKit';const DOMAIN = 0x0000;//必须是rpc.Parcelable类型
class Params implements rpc.Parcelable {marshalling(dataOut: rpc.MessageSequence): boolean {return true;}unmarshalling(dataIn: rpc.MessageSequence): boolean {return true;}
}class CardParams {count: number = 0formId:string = ""
}export default class EntryAbility extends UIAbility {onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');this.callee.on("updateFormCount", (data) => {const res = JSON.parse(data.readString()) as CardParams;AppStorage.setOrCreate('count', res.count);//必须返回一个rpc.Parcelable类型return new Params();})}onDestroy(): void {//销毁时解除监听this.callee.off("updateFormCount")hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');}onWindowStageCreate(windowStage: window.WindowStage): void {// Main window is created, set main page for this abilityhilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');windowStage.loadContent('pages/Index', (err) => {if (err.code) {hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));return;}hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');});}onWindowStageDestroy(): void {// Main window is destroyed, release UI related resourceshilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');}onForeground(): void {// Ability has brought to foregroundhilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground');}onBackground(): void {// Ability has back to backgroundhilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground');}
}
  1. 主页Index.ets
import { preferences } from '@kit.ArkData'
import { formBindingData, formProvider } from '@kit.FormKit'@Component
@Entry
struct Index {@StorageLink('count')count:number = 0build() {Column(){Text('课程太多了').fontSize(18).fontColor(Color.Orange).fontWeight(700)Row({ space: 20 }) {Button('++').onClick(() => {this.count++;})Text(this.count.toString()).fontSize(18)Button('--').onClick(() => {if (this.count > 0) {this.count--;}})}}.backgroundColor(Color.Pink).width('100%').height('100%')}
}

总结:如图示
在这里插入图片描述

5.2 应用----------->卡片
  1. 卡片的ability的entryformability的onAddForm方法中添加
onAddForm(want: Want) {// Called to return a FormBindingData object.return formBindingData.createFormBindingData({formId: want.parameters!["ohos.extra.param.key.form_identity"] as string});}
  1. 卡片:WidgetCard.ets 监听formId ,当formId发生变化时,发送至应用
 @LocalStorageProp("formId")@Watch("updateFormId")formId: string = ""updateFormId () {postCardAction(this, {action: 'call',abilityName: 'EntryAbility', // 只能跳转到当前应用下的UIAbilityparams: {method: 'updateFormId',formId: this.formId}})}
  1. 在ability中通过callee监听方法,将formId存入持久化
 this.callee.on("updateFormId", (data) => {const res = JSON.parse(data.readString()) as CardParamsconst store = preferences.getPreferencesSync(this.context, {name: 'formIdList'})const list = JSON.parse(store.getSync("formIdList", "[]") as string) as string[]if(!list.includes(res.formId)) {list.push(res.formId)}store.putSync("formIdList", JSON.stringify(list))store.flush()formProvider.updateForm(res.formId, formBindingData.createFormBindingData({num: AppStorage.get("num")}))return new Params()})
  1. 卸载时解除
  onDestroy(): void {this.callee.off("updateNum")this.callee.off("updateFormId")hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');}
  1. Index.ets
@StorageLink("num")@Watch("pushCard")num: number = 0pushCard() {const store = preferences.getPreferencesSync(getContext(), {name: 'formIdList'})const formIdList = JSON.parse(store.getSync("formIdList", "[]") as string) as string[]if (formIdList && formIdList.length) {formIdList.forEach((formId) => {formProvider.updateForm(formId, formBindingData.createFormBindingData({num: this.num}))})}}
  1. 卡片:从推送的数据中从新获取
@Entry
@Component
struct WidgetCard {//修改成@LocalStorageProp@LocalStorageProp("count")  count: number = 0;@LocalStorageProp("formId")@Watch("updateFormId")formId:string = ""//应用===》卡片  需要把formId给到应用updateFormId(){postCardAction(this,{action:'call',abilityName: 'EntryAbility',params:{method:'updateFormId',formId:this.formId}})}build() {Column() {Row({ space: 20 }) {Button('++').onClick(() => {this.count++;postCardAction(this, {action: 'call',abilityName: 'EntryAbility',params: {method: 'updateFormCount',count: this.count}})})Text(this.count.toString()).fontSize(18)Button('--').onClick(() => {if (this.count > 0) {this.count--;postCardAction(this,{action:'call',abilityName: 'EntryAbility',params:{method:'updateFormCount',count:this.count}})}})}}.justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center).width('100%').height('100%').onClick(() => {postCardAction(this, {action: 'router',abilityName: 'EntryAbility'})})}
}

总结:如图示:

在这里插入图片描述

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

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

相关文章

反向传播及优化器

反向传播(Backpropagation)反向传播是计算梯度的算法,核心作用是高效求解 “损失函数对模型所有参数的偏导数”(即梯度)。没有反向传播,深度学习的大规模训练几乎不可能实现。 整个过程像 “从终点回溯到起…

【机器学习深度学习】生成式模型的评估与验证

目录 前言 1. 主观评估:以人为本的质量判断 1.1 什么是主观评估? 1.2 主观评估的核心流程 1.3 主观评估的优缺点 2. 客观评估:量化的性能衡量 2.1 什么是客观评估? 2.2 常见的客观评估指标 文本生成 图像生成 多模态生…

Linux文件——Ext2文件系统(3)_软硬链接

文章目录文件的软硬链接软链接硬链接软硬链接对比软硬链接应用软硬链接注意事项总结文件的软硬链接 本篇文章将重点讲解文件系统中的一个重要的知识点: 即文件的软硬链接。 软链接 对于软链接的讲解,我们先来使用一个指令看看效果:ln -s 被…

Java SE:类与对象的认识

Java中的类与对象:构建程序世界的基石 在Java编程的世界里,类与对象是面向对象编程(OOP)的核心概念,它们就像构建大厦的砖瓦,支撑起整个程序的结构。理解类与对象,是掌握Java编程的关键一步。 类…

Hexo - 免费搭建个人博客03 - 将个人博客托管到github,个人博客公开给大家访问

导言我的博客:https://q164129345.github.io/ 既然要将个人博客托管到github,首先我们肯定要有一个github账户。另外也需要在电脑上安装另外一个著名的代码管理工具git。 一、创建github仓库二、在Hexo设置部署的内容# Deployment## Docs: https://hexo.…

一次Oracle集群脑裂问题分析处理

问题描述 填写问题的基础信息。 系统名称 数据库集群 IP地址 xxxxxx 操作系统 Linux 数据库 Oracle 11.2.0.4 症状表现 问题的症状表现如下 4月26号晚22点02分左右,HIS集群发生脑裂,十几分钟后(22.18)一节点集群率先获…

0基础法考随手笔记 02(刑诉法专题04 辩护与代理)

0基础法考随手笔记 02(刑诉法专题04 辩护与代理) 1.值班律师相关权力义务2. 3. 4.什么是强制医疗 注意:为强制医疗指派的律师,是诉讼代理人,不是辩护人,因为此人不会被追究刑事责任。 “强制医疗” 是刑事诉…

HF86611_VC1/HF86611Q_VC1:多通道USB HiFi音频解码器固件技术解析

引言随着音频技术的不断发展,多通道音频处理和多接口兼容性成为现代音频设备的重要需求。本文将介绍一款基于XMOS XU316技术的多通道USB HiFi音频解码器固件——HF86611_VC1/HF86611Q_VC1,这是一款专为多接口HiFi音频应用设计的软件解决方案。产品概述HF…

python---列表(List)

文章目录创建列表基本操作访问元素(索引)切片操作修改列表常用方法列表推导式多维列表列表是 Python 中最基本、最常用的数据结构之一,它是一个有序的可变集合,可以包含不同类型的元素。创建列表 # 空列表 empty_list [] empty_…

ESP32-S3学习笔记<3>:UART的应用

ESP32-S3学习笔记<3>:UART的应用1. 头文件包含2. UART的配置2.1 uart_num的选择2.2 uart_config的设定2.2.1 baud_rate/波特率设置2.2.2 data_bits/数据位数设置2.2.3 parity/奇偶校验位设置2.2.4 stop_bits/停止位设置2.2.5 flow_ctrl/流控位…

【Vue3】加载高德地图案例

官方API:展示地图-入门教程-地图 JS API 2.0 | 高德地图API 1、获取高德Key 参考:准备-地图 JS API 2.0 | 高德地图API 2、创建工程 npm create vitelatest 3、下载依赖集运行项目 npm install npm i amap/amap-jsapi-loader --save npm run dev 4、编写核心…

【工具】Pycharm隐藏侧边灯泡提示

问题描述 在Pycharm中,每行前面很容易出现一个小灯泡,有时候很影响操作,需要将其取消掉设置方法打开设置 按 CtrlAltS 打开设置对话框或者通过菜单 File → Settings(在 macOS 上是 PyCharm → Preferences)导航到外观…

XSS相关理解

由于本人对一小部分dom型xss、原型链污染和存储型xss理解不够透彻,因此在本篇文章中原型链污染和存储型xss偏重进行概念理解或简单的代码理解,随后会慢慢补充 文章目录1 XSS概述1.1 什么是XSS?1.2 XSS主要分三种类型2 XSS基础2.1 XSS基础练习…

Odoo:免费开源的金属制品行业ERP管理软件

引言开源智造Odoo数字化解决方案专家团队意识到,在当今全球市场中,将盈利能力和竞争力最大化的机会促使许多金属制品制造商投资于推进业务发展的新技术。金属制品会计软件是企业用来处理他们业务和增加利润的解决方案。某金属制品加工工艺流程图&#xf…

Ubuntu22.04配置GTest测试框架

前言 鸿蒙系统的代码仓库使用GTest作为单元测试的工具。特性开发时,需要写demo以验证开发思路。因此有必要搭建GTest开发环境配合鸿蒙特性开发做开发demo。 我测试环境是wsl2 Ubuntu22.04 LTS。 搭建过程 安装必备C组件 sudo apt install -y unzip g gcc cmake …

学习日志15 python

1 filter() 函数filter(function, iterable)filter函数是python中的高阶函数, 第一个参数是一个筛选函数, 第二个参数是一个可迭代对象, 返回的是一个生成器类型, 可以通过next获取值。filter() 函数是 Python 内置的高阶函数,其主要功能是对可迭代对象中的每个元素…

Linux 环境下安装 MySQL 8.0.34 二进制 详细教程 附docker+k8s启动

文章目录Linux 环境下安装 MySQL 8.0(二进制)详细教程准备工作安装依赖包下载并解压 MySQL下载 MySQL 二进制包解压 MySQL移动目录并创建 MySQL 用户配置 MySQL配置数据目录与日志目录编辑配置文件 /etc/my.cnf初始化 MySQL 数据库配置启动脚本与环境变量…

HTML ISO-8859-1: 完全解析

HTML ISO-8859-1: 完全解析 引言 ISO-8859-1,又称为 Latin-1,是一种广泛使用的字符编码标准,特别是在HTML文档中。本文将详细介绍ISO-8859-1编码的特点、应用场景以及如何在使用HTML时正确地使用ISO-8859-1编码。 ISO-8859-1编码概述 定义 ISO-8859-1编码是一种单字节编…

c++学习第3篇编辑器——centos7.9.2009系统离线安装clion软件并成功调试c++程序

远程linux服务器安装clion0 前提2个:1 下载CLion-2021.1.1.tar.gz安装包2 上传到linux系统并解压3 修改linux系统里的/etc/ssh/sshd_config文件中的X11UseLocalhost 注释去掉并设为no4 安装xauth5 安装MobaXterm软件并使用ssh组件打开clion5.1 如果打不开clion,报错…

20250722解决在Ubuntu 24.04.2下编译RD-RK3588开发板的Android13出现找不到lz4的问题

20250722解决在Ubuntu 24.04.2下编译RD-RK3588开发板的Android13出现找不到lz4的问题 2025/7/22 15:21缘起:在Ubuntu 24.04.2下编译RD-RK3588开发板的Android13。 报错:/bin/sh: 1: lz4: not found为了简单起见,直接在 荣品的技术支持QQ群的 …