日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HarmonyOS之深入解析服务卡片的使用

發(fā)布時(shí)間:2024/5/21 编程问答 112 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HarmonyOS之深入解析服务卡片的使用 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、概述

① 基本概念
  • 服務(wù)卡片(以下簡稱“卡片”)是 FA 的一種界面展示形式,將 FA 的重要信息或操作前置到卡片,以達(dá)到服務(wù)直達(dá),減少體驗(yàn)層級的目的。
  • 卡片常用于嵌入到其他應(yīng)用(當(dāng)前只支持系統(tǒng)應(yīng)用)中作為其界面的一部分顯示,并支持拉起頁面,發(fā)送消息等基礎(chǔ)的交互功能。卡片使用方負(fù)責(zé)顯示卡片。
  • 服務(wù)卡片如下圖所示:

  • 卡片使用方:顯示卡片內(nèi)容的宿主應(yīng)用,控制卡片在宿主中展示的位置。
  • 卡片管理服務(wù):用于管理系統(tǒng)中所添加卡片的常駐代理服務(wù),包括卡片對象的管理與使用,以及卡片周期性刷新等。
  • 卡片提供方:提供卡片顯示內(nèi)容的 HarmonyOS 應(yīng)用或原子化服務(wù),控制卡片的顯示內(nèi)容、控件布局以及控件點(diǎn)擊事件。
  • 卡片使用方和提供方不要求常駐運(yùn)行,在需要添加/刪除/請求更新卡片時(shí),卡片管理服務(wù)會(huì)拉起卡片提供方獲取卡片信息。
  • 卡片提供方控制卡片實(shí)際顯示的內(nèi)容、控件布局以及控件點(diǎn)擊事件。
② 運(yùn)作機(jī)制

  • 卡片管理服務(wù)包含以下模塊:
    • 周期性刷新:在卡片添加后,根據(jù)卡片的刷新策略啟動(dòng)定時(shí)任務(wù)周期性觸發(fā)卡片的刷新。
    • 卡片緩存管理:在卡片添加到卡片管理服務(wù)后,對卡片的視圖信息進(jìn)行緩存,以便下次獲取卡片時(shí)可以直接返回緩存數(shù)據(jù),降低時(shí)延。
    • 卡片生命周期管理:對于卡片切換到后臺或者被遮擋時(shí),暫停卡片的刷新;以及卡片的升級/卸載場景下對卡片數(shù)據(jù)的更新和清理。
    • 卡片使用方對象管理:對卡片使用方的 RPC 對象進(jìn)行管理,用于使用方請求進(jìn)行校驗(yàn)以及對卡片更新后的回調(diào)處理。
    • 通信適配層:負(fù)責(zé)與卡片使用方和提供方進(jìn)行 RPC 通信。
  • 卡片提供方包含以下模塊:
    • 卡片服務(wù):由卡片提供方開發(fā)者實(shí)現(xiàn),開發(fā)者實(shí)現(xiàn) onCreateForm、onUpdateForm 和 onDeleteForm 處理創(chuàng)建卡片、更新卡片以及刪除卡片等請求,提供相應(yīng)的卡片服務(wù)。
    • 卡片提供方實(shí)例管理模塊:由卡片提供方開發(fā)者實(shí)現(xiàn),負(fù)責(zé)對卡片管理服務(wù)分配的卡片實(shí)例進(jìn)行持久化管理。
    • 通信適配層:由 HarmonyOS SDK 提供,負(fù)責(zé)與卡片管理服務(wù)通信,用于將卡片的更新數(shù)據(jù)主動(dòng)推送到卡片管理服務(wù)。

二、API 說明

  • 卡片提供方接口功能:
類名接口名描述AbilityProviderFormInfo onCreateForm(Intent intent)卡片提供方接收創(chuàng)建卡片通知接口void onUpdateForm(long formId)卡片提供方接收更新卡片通知接口void onDeleteForm(long formId)卡片提供方接收刪除卡片通知接口void onTriggerFormEvent(long formId, String message)卡片提供方處理卡片事件接口(JS卡片使用)boolean updateForm(long formId, ComponentProvider component)卡片提供方主動(dòng)更新卡片(Java卡片使用)boolean updateForm(long formId, FormBindingData formBindingData)卡片提供方主動(dòng)更新卡片(JS卡片使用),僅更新formBindingData中攜帶的信息,卡片中其余信息保持不變void onCastTempForm(long formId)卡片提供方接收臨時(shí)卡片轉(zhuǎn)常態(tài)卡片通知 void onEventNotify(Map < Long, Integer > formEvents) 卡片提供方接收到事件通知,其中Ability.FORM_VISIBLE表示卡片可見通知, Ability.FORM_INVISIBLE表示卡片不可見通知FormState onAcquireFormState(Intent intent)卡片提供方接收查詢卡片狀態(tài)通知接口,默認(rèn)返回卡片初始狀態(tài)ProviderFormInfoProviderFormInfo(int resId, Context context)Java卡片返回對象構(gòu)造函數(shù)ProviderFormInfo()JS卡片返回對象構(gòu)造函數(shù)void mergeActions(ComponentProvider componentProviderActions)在提供方側(cè)調(diào)用該接口,將開發(fā)者在ComponentProvider中設(shè)置的actions配置數(shù)據(jù)合并到當(dāng)前對象中void setJsBindingData(FormBindingData data)設(shè)置JS卡片的內(nèi)容信息(JS卡片使用)
  • onEventNotify 僅系統(tǒng)應(yīng)用才會(huì)回調(diào),其他接口回調(diào)時(shí)機(jī)如下圖:

  • 卡片管理服務(wù)不負(fù)責(zé)保持卡片的活躍狀態(tài)(設(shè)置了定時(shí)更新的除外),當(dāng)使用方作出相應(yīng)的請求時(shí),管理服務(wù)會(huì)拉起提供方并回調(diào)相應(yīng)接口。

三、Java 卡片與 JS 卡片選型

  • Java/JS 卡片場景能力差異如下表所示:
場景Java卡片JS卡片支持的版本
實(shí)時(shí)刷新(類似時(shí)鐘)Java使用ComponentProvider做實(shí)時(shí)刷新代價(jià)比較大JS可以做到端側(cè)刷新,但是需要定制化組件HarmonyOS 2.0及以上
開發(fā)方式Java UI在卡片提供方需要同時(shí)對數(shù)據(jù)和組件進(jìn)行處理,生成ComponentProvider遠(yuǎn)端渲染JS卡片在使用方加載渲染,提供方只要處理數(shù)據(jù)、組件和邏輯分離HarmonyOS 2.0及以上
組件支持Text、Image、DirectionalLayout、PositionLayout、DependentLayoutdiv、list、list-item、swiper、stack、image、text、span、progress、button(定制:chart 、clock、calendar)HarmonyOS 2.0及以上
卡片內(nèi)動(dòng)效不支持暫不開放HarmonyOS 2.0及以上
陰影模糊不支持支持HarmonyOS 2.0及以上
動(dòng)態(tài)適應(yīng)布局不支持支持HarmonyOS 2.0及以上
自定義卡片跳轉(zhuǎn)頁面不支持支持HarmonyOS 2.0及以上
  • 綜上所述,JS 卡片比 Java 卡片支持的控件和能力都更豐富:
    • Java 卡片:適合作為一個(gè)直達(dá)入口,沒有復(fù)雜的頁面和事件。
    • JS 卡片:適合有復(fù)雜界面的卡片。
  • 對于同一個(gè) Page ability,在 config.json 中最多支持配置 16 張卡片。

三、創(chuàng)建服務(wù)卡片

① 卡片目錄結(jié)構(gòu)
  • JS 服務(wù)卡片(entry/src/main/js/Component)的典型開發(fā)目錄結(jié)構(gòu)如下:

  • 目錄結(jié)構(gòu)中文件分類如下:
    • .hml 結(jié)尾的 HML 模板文件,這個(gè)文件用來描述卡片頁面的模板布局結(jié)構(gòu);
    • .css 結(jié)尾的 CSS 樣式文件,這個(gè)文件用于描述頁面樣式;
    • .json 結(jié)尾的 JSON 文件,這個(gè)文件用于配置卡片中使用的變量 action 事件。
  • 各個(gè)文件夾的作用:
    • pages 目錄用于存放卡片模板頁面;
    • common 目錄用于存放公共資源文件,比如:圖片資源;
    • resources 目錄用于存放資源配置文件,比如:多分辨率加載配置文件;
    • i18n 目錄用于配置不同語言場景資源內(nèi)容,比如應(yīng)用文本詞條,圖片路徑等資源。
② 卡片創(chuàng)建
  • 對于創(chuàng)建新工程,可以在工程向?qū)е泄催x“Show in Service Center”,該參數(shù)表示是否在服務(wù)中心露出。如果 Project Type 為 Service,則會(huì)同步創(chuàng)建一個(gè) 22 的服務(wù)卡片模板,同時(shí)還會(huì)創(chuàng)建入口卡片;如果 Project Type 為 Application,則只會(huì)創(chuàng)建一個(gè) 22 的服務(wù)卡片模板:

  • 卡片創(chuàng)建完成后,會(huì)在工程目錄下生成 EntryCard 目錄:

  • 在該目錄下,每個(gè)擁有 EntryCard 的模塊,都會(huì)生成一個(gè)和模塊名相同的文件夾,同時(shí)還會(huì)默認(rèn)生成一張 2x2 的快照型 EntryCard 圖片(png 格式)。
  • 可以將其替換為提前設(shè)計(jì)好的 2x2 快照圖:將新的快照圖拷貝到上圖目錄下,刪除默認(rèn)圖片,新圖片命名遵循格式“卡片名稱-2x2.png”。
  • 在已有工程中添加新模塊,也可以添加服務(wù)卡片和 EntryCard,只需在創(chuàng)建模塊時(shí),勾選“Show in Service Center”即可。創(chuàng)建出來的服務(wù)卡片和 EntryCard,同創(chuàng)建新工程生成的一致。
  • 在已有工程中,只添加 EntryCard,只能通過手工方式,按照上圖中的 EntryCard 目錄創(chuàng)建對應(yīng)的文件夾和圖片。
  • 在已有工程中,新添加服務(wù)卡片,可以通過如下方法進(jìn)行創(chuàng)建:
    • 打開一個(gè)工程,創(chuàng)建服務(wù)卡片模板,創(chuàng)建方法包括如下兩種方式:
      • 選擇模塊(如entry模塊)下的任意文件,點(diǎn)擊菜單欄 File > New > Service Widget創(chuàng)建服務(wù)卡片;
      • 選擇模塊(如entry模塊)下的任意文件,點(diǎn)擊右鍵 > New > Service Widget創(chuàng)建服務(wù)卡片。
    • 在 Choose a template for your service widget 界面中,選擇需要?jiǎng)?chuàng)建的卡片模板,點(diǎn)擊 Next:

    • 在 Configure Your Service Widget 界面中,配置卡片的基本信息,包括:
      Service Widget Name:卡片的名稱,在同一個(gè) FA 中,卡片名稱不能重復(fù),且只能包含數(shù)字、字母和下劃線。
      • Description:卡片的描述信息;
      • Select Ability/New Ability:選擇一個(gè)掛靠服務(wù)卡片的 Page Ability,或者創(chuàng)建一個(gè)新的 Page Ability;
      • Type:卡片的開發(fā)語言類型;
      • JS Component Name:Type 選擇 JS 時(shí)需要設(shè)置卡片的 JS Component 名稱;
      • Support Dimensions:選擇卡片的規(guī)格,部分卡片支持同時(shí)設(shè)置多種規(guī)格;

    • 點(diǎn)擊 Finish 完成卡片的創(chuàng)建。創(chuàng)建完成后,工具會(huì)自動(dòng)創(chuàng)建出服務(wù)卡片的布局文件,并在 config.json 文件中寫入服務(wù)卡片的屬性字段:

    • 卡片創(chuàng)建完成后,請根據(jù) Java 卡片開發(fā)或 JS 卡片開發(fā),完成服務(wù)卡片的開發(fā)。

四、JS 卡片開發(fā)

① 使用 hml+css+json 開發(fā) JS 卡片頁面
  • 使用 DevEco Studio 創(chuàng)建卡片工程
    • 創(chuàng)建成功后,在 config.json 的 module 中會(huì)生成 js 模塊,用于對應(yīng)卡片的 js 相關(guān)資源,配置示例如下:
"js": [{"name": "card","pages": ["pages/index/index"],"window": {"designWidth": 720,"autoDesignWidth": true},"type": "form"}]
    • config.json 文件“abilities”配置 forms 模塊細(xì)節(jié)如下:
"forms": [{"name": "Form_Js","description": "form_description","type": "JS","jsComponentName": "card","formConfigAbility": "ability://com.huawei.demo.SecondFormAbility","colorMode": "auto","isDefault": true,"updateEnabled": true,"scheduledUpdateTime": "10:30","updateDuration": 1,"defaultDimension": "2*2","supportDimensions": ["2*2","2*4","4*4"],"metaData": {"customizeData": [{"name": "originWidgetName","value": "com.huawei.weather.testWidget"}]}}]
    • 配置文件中,應(yīng)注意如下配置:
      • “js”模塊中的 name 字段要與“forms”模塊中的 jsComponentName 字段的值一致,為 js 資源的實(shí)例名。
      • “forms”模塊中的 name 為卡片名,即在 onCreateForm 中根據(jù) AbilitySlice.PARAM_FORM_NAME_KEY 可取到的值。
      • 卡片的 Ability 中還需要配置"visible": true 和"formsEnabled": true。
      • 定時(shí)刷新和定點(diǎn)刷新都配置的情況下,定時(shí)刷新優(yōu)先。
      • defaultDimension 是默認(rèn)規(guī)格,必須設(shè)置。
    • forms 對象的內(nèi)部結(jié)構(gòu)說明:
屬性名稱子屬性名稱含義數(shù)據(jù)類型是否可缺省name-表示卡片的類名,字符串最大長度為127字節(jié)字符串否description-表示卡片的描述,取值可以是描述性內(nèi)容,也可以是對描述性內(nèi)容的資源索引,以支持多語言。字符串最大長度為255字節(jié)字符串可缺省,缺省為空isDefault-表示該卡片是否為默認(rèn)卡片,每個(gè)Ability有且只有一個(gè)默認(rèn)卡片
true:默認(rèn)卡片
false:非默認(rèn)卡片布爾值否type-表示卡片的類型,取值范圍如下:
Java:Java卡片
JS:JS卡片字符串否colorMode-表示卡片的主題樣式,取值范圍如下:
auto:自適應(yīng)
dark:深色主題
light:淺色主題字符串可缺省,缺省值為“auto”supportDimensions-表示卡片支持的外觀規(guī)格,取值范圍:
1*2:表示1行2列的二宮格
2*2:表示2行2列的四宮格
2*4:表示2行4列的八宮格
4*4:表示4行4列的十六宮格字符串?dāng)?shù)組否defaultDimension-表示卡片的默認(rèn)外觀規(guī)格,取值必須在該卡片supportDimensions配置的列表中字符串否landscapeLayouts-表示卡片外觀規(guī)格對應(yīng)的橫向布局文件,與supportDimensions中的規(guī)格一一對應(yīng),僅當(dāng)卡片類型為Java卡片時(shí),需要配置該標(biāo)簽字符串?dāng)?shù)組否portraitLayouts-表示卡片外觀規(guī)格對應(yīng)的豎向布局文件,與supportDimensions中的規(guī)格一一對應(yīng),僅當(dāng)卡片類型為Java卡片時(shí),需要配置該標(biāo)簽字符串?dāng)?shù)組否updateEnabled-表示卡片是否支持周期性刷新,取值范圍: true:表示支持周期性刷新,可以在定時(shí)刷新(updateDuration)和定點(diǎn)刷新(scheduledUpdateTime)兩種方式任選其一,優(yōu)先選擇定時(shí)刷新
false:表示不支持周期性刷新布爾類型否scheduledUpdateTime-表示卡片的定點(diǎn)刷新的時(shí)刻,采用24小時(shí)制,精確到分鐘字符串可缺省,缺省值為“0:0”updateDuration-表示卡片定時(shí)刷新的更新周期,單位為30分鐘,取值為自然數(shù): 當(dāng)取值為0時(shí),表示該參數(shù)不生效;當(dāng)取值為正整數(shù)N時(shí),表示刷新周期為30*N分鐘數(shù)值可缺省,缺省值為“0”formConfigAbility-表示卡片的配置跳轉(zhuǎn)鏈接,采用URI格式字符串可缺省,缺省值為空jsComponentName-表示JS卡片的Component名稱,字符串最大長度為127字節(jié),僅當(dāng)卡片類型為JS卡片時(shí),需要配置該標(biāo)簽字符串否metaData-表示卡片的自定義信息,包含customizeData數(shù)組標(biāo)簽對象可缺省,缺省值為空customizeData-表示自定義的卡片信息對象數(shù)組可缺省,缺省值為空name表示數(shù)據(jù)項(xiàng)的鍵名稱,字符串最大長度為255字節(jié)字符串可缺省,缺省值為空value表示數(shù)據(jù)項(xiàng)的值,字符串最大長度為255字節(jié)字符串可缺省,缺省值為空
  • 創(chuàng)建一個(gè) FormAbility,覆寫卡片相關(guān)回調(diào)函數(shù)
    • 回調(diào)函數(shù)
      • onCreateForm(Intent intent)
      • onUpdateForm(long formId)
      • onDeleteForm(long formId)
      • onCastTempForm(long formId)
      • onEventNotify(Map<Long, Integer> formEvents)
      • onTriggerFormEvent(long formId, String message)
      • onAcquireFormState(Intent intent)
    • 當(dāng)卡片使用方請求獲取卡片時(shí),卡片提供方會(huì)被拉起并調(diào)用 onCreateForm(Intent intent) 回調(diào),intent 中會(huì)帶有卡片 ID、卡片名稱和卡片外觀規(guī)格信息,可按需獲取使用。
    • 開發(fā) JS 卡片時(shí),FormAbility 可以繼承 AceAbility 或 Ability,繼承 Ability 時(shí),需在 onStart() 方法中額外設(shè)置路由信息。
    • FormAbility 繼承 AceAbility 的代碼示例:
public class FormAbility extends AceAbility {......public static long formId = -1;@Overridepublic void onStart(Intent intent) {super.onStart(intent);}@Overrideprotected ProviderFormInfo onCreateForm(Intent intent) {long formId = intent.getLongParam(AbilitySlice.PARAM_FORM_IDENTITY_KEY, 0);String formName = intent.getStringParam(AbilitySlice.PARAM_FORM_NAME_KEY);int specificationId = intent.getIntParam(AbilitySlice.PARAM_FORM_DIMENSION_KEY, 0);boolean tempFlag = intent.getBooleanParam(AbilitySlice.PARAM_FORM_TEMPORARY_KEY, false);HiLog.info(LABEL_LOG, "onCreateForm: " + formId + " " + formName + " " + specificationId);FormBindingData formBindingData = new FormBindingData("{\"temperature\": \"60°\"}");ProviderFormInfo formInfo = new ProviderFormInfo();formInfo.setJsBindingData(formBindingData);return formInfo;}@Overrideprotected void onDeleteForm(long formId) {// 刪除卡片實(shí)例數(shù)據(jù)super.onDeleteForm(formId);......}@Overrideprotected void onUpdateForm(long formId) {// 若卡片支持定時(shí)更新/定點(diǎn)更新/卡片使用方主動(dòng)請求更新功能,則提供方需要覆寫該方法以支持?jǐn)?shù)據(jù)更新super.onUpdateForm(formId);......}@Overrideprotected void onTriggerFormEvent(long formId, String message) {// 若卡片支持觸發(fā)事件,則需要覆寫該方法并實(shí)現(xiàn)對事件的觸發(fā)super.onTriggerFormEvent(formId, message);......}@Overrideprotected void onCastTempForm(long formId) {//使用方將臨時(shí)卡片轉(zhuǎn)換為常態(tài)卡片觸發(fā),提供方需要做相應(yīng)的處理super.onCastTempForm (formId);......}@Overrideprotected void onEventNotify(Map<Long, Integer> formEvents) {//使用方發(fā)起可見或者不可見通知觸發(fā),提供方需要做相應(yīng)的處理super.onEventNotify(formEvents);......}@Overrideprotected FormState onAcquireFormState(Intent intent) {ElementName elementName = intent.getElement();if (elementName == null) {HiLog.info(LABEL_LOG, "onAcquireFormState bundleName and abilityName are not set in intent");return FormState.UNKNOWN;}String bundleName = elementName.getBundleName();String abilityName = elementName.getAbilityName();String moduleName = intent.getStringParam(AbilitySlice.PARAM_MODULE_NAME_KEY);String formName = intent.getStringParam(AbilitySlice.PARAM_FORM_NAME_KEY);int specificationId = intent.getIntParam(AbilitySlice.PARAM_FORM_DIMENSION_KEY, 0);if ("form_name2".equals(formName)) {return FormState.DEFAULT;}return FormState.READY;}}
    • FormAbility 繼承 Ability 的代碼示例:
public class FormAbility extends Ability {......public static long formId = -1;@Overridepublic void onStart(Intent intent) {super.onStart(intent);super.setMainRoute(FormAbilitySlice.class.getName()); //設(shè)置路由}@Overrideprotected ProviderFormInfo onCreateForm(Intent intent) {long formId = intent.getLongParam(AbilitySlice.PARAM_FORM_IDENTITY_KEY, 0);String formName = intent.getStringParam(AbilitySlice.PARAM_FORM_NAME_KEY);int specificationId = intent.getIntParam(AbilitySlice.PARAM_FORM_DIMENSION_KEY, 0);boolean tempFlag = intent.getBooleanParam(AbilitySlice.PARAM_FORM_TEMPORARY_KEY, false);HiLog.info(LABEL_LOG, "onCreateForm: " + formId + " " + formName + " " + specificationId);FormBindingData formBindingData = new FormBindingData("{\"temperature\": \"60°\"}");ProviderFormInfo formInfo = new ProviderFormInfo();formInfo.setJsBindingData(formBindingData);return formInfo;}@Overrideprotected void onDeleteForm(long formId) {// 刪除卡片實(shí)例數(shù)據(jù)super.onDeleteForm(formId);......}@Overrideprotected void onUpdateForm(long formId) {// 若卡片支持定時(shí)更新/定點(diǎn)更新/卡片使用方主動(dòng)請求更新功能,則提供方需要覆寫該方法以支持?jǐn)?shù)據(jù)更新super.onUpdateForm(formId);......}@Overrideprotected void onTriggerFormEvent(long formId, String message) {// 若卡片支持觸發(fā)事件,則需要覆寫該方法并實(shí)現(xiàn)對事件的觸發(fā)super.onTriggerFormEvent(formId, message);......}@Overrideprotected void onCastTempForm(long formId) {//使用方將臨時(shí)卡片轉(zhuǎn)換為常態(tài)卡片觸發(fā),提供方需要做相應(yīng)的處理super.onCastTempForm (formId);......}@Overrideprotected void onEventNotify(Map<Long, Integer> formEvents) {//使用方發(fā)起可見或者不可見通知觸發(fā),提供方需要做相應(yīng)的處理super.onEventNotify(formEvents);......}@Overrideprotected FormState onAcquireFormState(Intent intent) {ElementName elementName = intent.getElement();if (elementName == null) {HiLog.info(LABEL_LOG, "onAcquireFormState bundleName and abilityName are not set in intent");return FormState.UNKNOWN;}String bundleName = elementName.getBundleName();String abilityName = elementName.getAbilityName();String moduleName = intent.getStringParam(AbilitySlice.PARAM_MODULE_NAME_KEY);String formName = intent.getStringParam(AbilitySlice.PARAM_FORM_NAME_KEY);int specificationId = intent.getIntParam(AbilitySlice.PARAM_FORM_DIMENSION_KEY, 0);if ("form_name2".equals(formName)) {return FormState.DEFAULT;}return FormState.READY;}}
  • 卡片信息持久化
    • 因大部分卡片提供方都不是常駐服務(wù),只有在需要使用時(shí)才會(huì)被拉起獲取卡片信息,且卡片管理服務(wù)支持對卡片進(jìn)行多實(shí)例管理,卡片 ID 對應(yīng)實(shí)例 ID,因此若卡片提供方支持對卡片數(shù)據(jù)進(jìn)行配置,則需要對卡片的業(yè)務(wù)數(shù)據(jù)按照卡片 ID 進(jìn)行持久化管理,以便在后續(xù)獲取、更新以及拉起時(shí)能獲取到正確的卡片業(yè)務(wù)數(shù)據(jù)。且需要適配 onDeleteForm(long formId) 卡片刪除通知接口,在其中實(shí)現(xiàn)卡片實(shí)例數(shù)據(jù)的刪除。
    • 常態(tài)卡片:卡片使用方會(huì)持久化的卡片;
    • 臨時(shí)卡片:卡片使用方不會(huì)持久化的卡片;
    • 需要注意的是,卡片使用方在請求卡片時(shí)傳遞給提供方應(yīng)用的 Intent 數(shù)據(jù)中存在臨時(shí)標(biāo)記字段,表示此次請求的卡片是否為臨時(shí)卡片,由于臨時(shí)卡片的數(shù)據(jù)具有非持久化的特殊性,某些場景比如卡片服務(wù)框架死亡重啟,此時(shí)臨時(shí)卡片數(shù)據(jù)在卡片管理服務(wù)中已經(jīng)刪除,且對應(yīng)的卡片 ID 不會(huì)通知到提供方,所以卡片提供方需要自己負(fù)責(zé)清理長時(shí)間未刪除的臨時(shí)卡片數(shù)據(jù)。同時(shí)對應(yīng)的卡片使用方可能會(huì)將之前請求的臨時(shí)卡片轉(zhuǎn)換為常態(tài)卡片。如果轉(zhuǎn)換成功,卡片提供方也需要對對應(yīng)的臨時(shí)卡片 ID 進(jìn)行處理,把卡片提供方記錄的臨時(shí)卡片數(shù)據(jù)轉(zhuǎn)換為常態(tài)卡片數(shù)據(jù),防止提供方在清理長時(shí)間未刪除的臨時(shí)卡片時(shí),把已經(jīng)轉(zhuǎn)換為常態(tài)卡片的臨時(shí)卡片信息刪除,導(dǎo)致卡片信息丟失。
@Overrideprotected ProviderFormInfo onCreateForm(Intent intent) {long formId = intent.getIntParam(AbilitySlice.PARAM_FORM_IDENTITY_KEY, -1L);String formName = params.getStringParam(AbilitySlice.PARAM_FORM_NAME_KEY);int specificationId = params.getIntParam(AbilitySlice.PARAM_FORM_DIMENSION_KEY, 0);boolean tempFlag = params.getBooleanParam(AbilitySlice.PARAM_FORM_TEMPORARY_KEY, false);HiLog.info(LABEL_LOG, "onCreateForm: " + formId + " " + formName + " " + specificationId);.......// 由開發(fā)人員自行實(shí)現(xiàn),將創(chuàng)建的卡片信息持久化,以便在下次獲取/更新該卡片實(shí)例時(shí)進(jìn)行使用storeFormInfo(formId, formName, specificationId, formData);......HiLog.info(LABEL_LOG, "onCreateForm finish.......");return formInfo;}@Overrideprotected void onDeleteForm(long formId) {super.onDeleteForm(formId);// 由開發(fā)人員自行實(shí)現(xiàn),刪除卡片實(shí)例數(shù)據(jù)deleteFormInfo(formId);......}@Overrideprotected void onCastTempForm(long formId) {// 使用方將臨時(shí)卡片轉(zhuǎn)換為常態(tài)卡片觸發(fā),提供方需要做相應(yīng)的處理super.onCastTempForm (formId);......}
  • 卡片數(shù)據(jù)交互
    • 當(dāng)卡片應(yīng)用需要更新數(shù)據(jù)時(shí)(如觸發(fā)了定時(shí)更新或定點(diǎn)更新),卡片應(yīng)用獲取最新數(shù)據(jù),并調(diào)用 updateForm 接口更新卡片。示例如下:
@Overrideprotected void onUpdateForm(long formId) {super.onUpdateForm(formId);ZSONObject zsonObject = new ZSONObject();zsonObject.put("temperature", "90°");FormBindingData formBindingData = new FormBindingData(zsonObject);// 調(diào)用updateForm接口去更新對應(yīng)的卡片,僅更新入?yún)⒅袛y帶的數(shù)據(jù)信息,其他信息保持不變if (!updateForm(formId, formBindingData)) {// err process}}
  • 開發(fā) JS 卡片頁面
    • JS 卡片頁面與普通 FA 類似通過 hml+css+json 開發(fā),示例如下:
hml:<div class="container"><stack class="stack_container"><image class = "img" src="common/clouds.png"></image><div style="flex-direction: column;"><text class="txt_city" onclick="messageEvent">{{city}}</text><text class="txt_temperature" onclick="routerEvent">{{temperature}}</text></div></stack></div>css:.container {flex-direction: column;justify-content: center;align-items: center;}.stack_container {width: 100%;height: 100%;background-image: url("/common/weather-background-day.png");background-size: cover;}...json:{"data": {"temperature": "35°","city": "hangzhou"},"actions": {"routerEvent": {"action": "router","abilityName": "com.example.myapplication.FormAbility","params": {"message": "weather"}},"messageEvent": {"action": "message","params": {"message": "weather update"}}}}
  • 開發(fā) JS 卡片事件和 action
    • JS 卡片支持為組件設(shè)置 action,包括 router 事件和 message 事件,其中 router 事件用于應(yīng)用跳轉(zhuǎn),message 事件用于卡片開發(fā)人員自定義點(diǎn)擊事件。
    • 關(guān)鍵步驟說明如下:
      • 在 hml 中為組件設(shè)置 onclick 屬性,其值對應(yīng)到 json 文件的 actions 字段中。
      • 若設(shè)置 router 事件,則
        • action 屬性值為"router";
        • abilityName 為卡片提供方應(yīng)用的跳轉(zhuǎn)目標(biāo) Ability 名;
        • params中的值按需填寫,其值在使用時(shí)通過 intent.getStringParam(“params”) 獲取即可;
      • 若設(shè)置 message 事件,則 action 屬性值為"message",params 為 json 格式的值。
hml:<text class="txt_city" onclick="messageEvent">{{city}}</text><text class="txt_temperature" onclick="routerEvent">{{temperature}}</text> json:{"actions": {"routerEvent": {"action": "router","abilityName": "com.example.myapplication.FormAbility","params": {"message": "weather"}},"messageEvent": {"action": "message","params": {"message": "test date",}}}}
  • 當(dāng)點(diǎn)擊組件觸發(fā) message 事件時(shí),卡片應(yīng)用的 onTriggerFormEvent 方法被觸發(fā), params 屬性的值將作為參數(shù)被傳入,解析使用即可。
  • message 事件由于是自定義,也可以在 message 事件中實(shí)現(xiàn)跳轉(zhuǎn)到其他 Ability 的能力。但是,在這種情況下,卡片使用方定義的動(dòng)效是不生效的。宿主側(cè)定義的動(dòng)效僅在 router 事件的跳轉(zhuǎn)中生效。
  • 如果想要保證動(dòng)效,使用 routerEvent。routerEvent 配置跳轉(zhuǎn)鏈接時(shí),只能配置到卡片提供方自己的 ability 中。
② 通過內(nèi)存圖片方式使用 image 組件
  • 在卡片上如果想要顯示網(wǎng)絡(luò)的圖片資源、數(shù)據(jù)庫中查詢讀取的圖片資源等圖片資源,可以通過 image 組件提供的內(nèi)存圖片能力。
  • 獲取圖片數(shù)據(jù):內(nèi)存圖片使用 byte[] 格式的圖片數(shù)據(jù),可以來自多個(gè)途徑:比如網(wǎng)絡(luò)的圖片資源、數(shù)據(jù)庫中查詢讀取的圖片資源、本地圖片打開后獲得的圖片資源等。
  • 調(diào)用 FormBindingData 的 addImageData 接口傳入數(shù)據(jù):
    • 首先創(chuàng)建一個(gè) ZSONObject,將{imageSrc,memory:// + picName}的鍵值對添加到 ZSONObject 中,其中,imageSrc 是 image 組件 src 屬性關(guān)聯(lián)的變量(比如在 js 文件中, image 組件的寫法是),picName 是共享內(nèi)存的圖片名,該命名可以自定義,但是要保證圖片格式的后綴名正確。
ZSONObject zsonObject = new ZSONObject();zsonObject.put("imageSrc", "memory://logo.png");
    • 使用該 ZSONObject 去創(chuàng)建一個(gè) FormBindingData。
    • 調(diào)用 FormBindingData 的 addImageData 接口添加數(shù)據(jù):addImageData(“l(fā)ogo.png”, bytes),其中,"logo.png"為 picName,必須和第一步里面添加到 ZSONObject 中的鍵值對的picName一致,否則1中的共享圖片路徑(“memory://logo.png”)將讀取不到這里添加進(jìn)去的圖片數(shù)據(jù)。
    • 如果是在卡片的 onCreateForm 生命周期去更新共享內(nèi)存圖片數(shù)據(jù),則只需創(chuàng)建 ProviderFormInfo,然后將 FormBindingData 設(shè)置給 ProviderFormInfo中,返回 ProviderFormInfo 即可。
    • 如果是在卡片的其他生命周期去更新共享內(nèi)存圖片數(shù)據(jù),直接調(diào)用 updateForm 去更新指定卡片即可,代碼示例在 onCreateForm 中使用。
<!-- xxx.hml --><image src="{{imageSrc}}"></image> // xxx.xxx.FormAbility@Overrideprotected ProviderFormInfo onCreateForm(Intent intent) {IntentParams params = intent.getParams();if (params == null) {return null;}formId = (int) params.getParam(AbilitySlice.PARAM_FORM_ID_KEY);String formName = (String) params.getParam(AbilitySlice.PARAM_FORM_NAME_KEY);int specificationId = (int) params.getParam(AbilitySlice.PARAM_FORM_DIMENSION_KEY);// ********************* memory image usage section *********************// Step1: Create [ZSONObject] and set [picName] of [imageSrc] to it// [imageSrc] is the variable we bind to the [src] attribute of image component in js// such as <image src="{{imageSrc}}"></image>ZSONObject zsonObject = new ZSONObject();zsonObject.put("imageSrc", "memory://logo.png"); // Step2: Construct a [FormbindingData] using the [ZSONObject] we just createdFormBindingData formBindingData = new FormBindingData(zsonObject);// Step3: Add image data to [FormBindingData] via interface: [addImageData]formBindingData.addImageData("logo.png", bytes);// ********************* memory image usage section *********************ProviderFormInfo formInfo = new ProviderFormInfo();formInfo.setJsBindingData(formBindingData);return formInfo;}

五、Java 卡片開發(fā)

① 使用 DevEco Studio 創(chuàng)建卡片工程
  • 卡片應(yīng)用是一款特殊的元能力服務(wù),其配置文件 config.json 中聲明以下幾項(xiàng),系統(tǒng)能夠識別該應(yīng)用為一款卡片應(yīng)用,并與系統(tǒng)進(jìn)行綁定。
  • config.json 文件 “abilities” 配置 forms 模塊細(xì)節(jié)如下:
"forms": [{"name": "Form_Java","description": "form_description","type": "Java","colorMode": "auto","isDefault": true,"updateEnabled": true,"scheduledUpdateTime": "10:30","updateDuration": 1,"defaultDimension": "2*2","formVisibleNotify": true,"supportDimensions": ["1*2","2*2","2*4","4*4"],"landscapeLayouts": ["$layout:form_ability_layout_1_2","$layout:form_ability_layout_2_2","$layout:form_ability_layout_2_4","$layout:form_ability_layout_4_4"],"portraitLayouts": ["$layout:form_ability_layout_1_2","$layout:form_ability_layout_2_2","$layout:form_ability_layout_2_4","$layout:form_ability_layout_4_4"],"formConfigAbility": "ability://SecondFormAbility","metaData": {"customizeData": [{"name": "originWidgetName","value": "com.huawei.weather.testWidget"}]}}]
  • "forms"模塊中的 name 為卡片名,即在 onCreateForm 中根據(jù) AbilitySlice.PARAM_FORM_NAME_KEY 可取到的值。
  • 在卡片所在的"abilities"中還需要配置"visible": true 和"formsEnabled": true。
② 創(chuàng)建一個(gè) FormAbility,覆寫卡片相關(guān)回調(diào)函數(shù)
  • 相關(guān)函數(shù):
    • onCreateForm(Intent intent)
    • onUpdateForm(long formId)
    • onDeleteForm(long formId)
    • onCastTempForm(long formId)
    • onEventNotify(Map<Long, Integer> formEvents)
    • onAcquireFormState(Intent intent)
  • 在 onCreateForm(Intent intent) 中,當(dāng)卡片使用方請求獲取卡片時(shí),卡片提供方會(huì)被拉起并調(diào)用 onCreateForm(Intent intent) 回調(diào),intent 中會(huì)帶有卡片 ID,卡片名稱,臨時(shí)卡片標(biāo)記和卡片外觀規(guī)格信息,分別通過 AbilitySlice.PARAM_FORM_IDENTITY_KEY、AbilitySlice.PARAM_FORM_NAME_KEY、AbilitySlice.PARAM_FORM_TEMORARY_KEY和AbilitySlice.PARAM_FORM_DIMENSION_KEY 按需獲取。
  • 提供方可以通過 AbilitySlice.PARAM_FORM_CUSTOMIZE_KEY 獲取卡片使用方設(shè)置的自定義數(shù)據(jù)。
public class FormAbility extends Ability {......@Overridepublic void onStart(Intent intent) {super.onStart(intent);......}@Overrideprotected ProviderFormInfo onCreateForm(Intent intent) {long formId = intent.getLongParam(AbilitySlice.PARAM_FORM_IDENTITY_KEY, 0);String formName = intent.getStringParam(AbilitySlice.PARAM_FORM_NAME_KEY);int specificationId = intent.getIntParam(AbilitySlice.PARAM_FORM_DIMENSION_KEY, 0);boolean tempFlag = intent.getBooleanParam(AbilitySlice.PARAM_FORM_TEMPORARY_KEY, false);// 獲取自定義數(shù)據(jù)IntentParams intentParams = intent.getParam(AbilitySlice.PARAM_FORM_CUSTOMIZE_KEY);HiLog.info(LABEL_LOG, "onCreateForm: " + formId + " " + formName + " " + specificationId);// 開發(fā)者需要根據(jù)卡片的名稱以及外觀規(guī)格獲取對應(yīng)的xml布局并構(gòu)造卡片對象,此處ResourceTable.Layout_form_ability_layout_2_2僅為示例ProviderFormInfo formInfo = new ProviderFormInfo(ResourceTable.Layout_form_ability_layout_2_2, this);// 獲取卡片信息String formData = getInitFormData(formName, specificationId);ComponentProvider componentProvider = new ComponentProvider();componentProvider.setText(ResourceTable.Id_title, "formData-" + formData);formInfo.mergeActions(componentProvider);......HiLog.info(LABEL_LOG, "onCreateForm finish.......");return formInfo;}@Overrideprotected void onDeleteForm(long formId) {super.onDeleteForm(formId);// 刪除卡片實(shí)例數(shù)據(jù),需要由開發(fā)者實(shí)現(xiàn)deleteFormInfo(formId);......}@Override// 若卡片支持定時(shí)更新/定點(diǎn)更新/卡片使用方主動(dòng)請求更新功能,則提供方需要覆寫該方法以支持?jǐn)?shù)據(jù)更新protected void onUpdateForm(long formId) {super.onUpdateForm(formId);// 更新卡片信息,由開發(fā)者實(shí)現(xiàn)......}@Overrideprotected void onCastTempForm(long formId) {// 使用方將臨時(shí)卡片轉(zhuǎn)換為常態(tài)卡片觸發(fā),提供方需要做相應(yīng)的處理,將數(shù)據(jù)持久化。super.onCastTempForm (formId);......}@Overrideprotected void onEventNotify(Map<Long, Integer> formEvents) {// 使用方發(fā)起可見或者不可見通知觸發(fā),提供方需要做相應(yīng)的處理,比如卡片可見時(shí)刷新卡片,僅系統(tǒng)應(yīng)用能收到該回調(diào)。super.onEventNotify(formEvents);......}@Overrideprotected FormState onAcquireFormState(Intent intent) {ElementName elementName = intent.getElement();if (elementName == null) {HiLog.info(LABEL_LOG, "onAcquireFormState bundleName and abilityName are not set in intent");return FormState.UNKNOWN;}String bundleName = elementName.getBundleName();String abilityName = elementName.getAbilityName();String moduleName = intent.getStringParam(AbilitySlice.PARAM_MODULE_NAME_KEY);String formName = intent.getStringParam(AbilitySlice.PARAM_FORM_NAME_KEY);int specificationId = intent.getIntParam(AbilitySlice.PARAM_FORM_DIMENSION_KEY, 0);if ("form_name2".equals(formName)) {return FormState.DEFAULT;}return FormState.READY;}}
③ 卡片信息持久化
  • 因大部分卡片提供方都不是常駐服務(wù),只有在需要使用時(shí)才會(huì)被拉起獲取卡片信息。且卡片管理服務(wù)支持對卡片進(jìn)行多實(shí)例管理,卡片 ID 對應(yīng)實(shí)例 ID,因此若卡片提供方支持對卡片數(shù)據(jù)進(jìn)行配置,則需要提供方對卡片的業(yè)務(wù)數(shù)據(jù)按照卡片 ID 進(jìn)行持久化管理,以便在后續(xù)獲取、更新以及拉起時(shí)能獲取到正確的卡片業(yè)務(wù)數(shù)據(jù)。
  • 同時(shí),需要適配 onDeleteForm(int formId) 卡片刪除通知接口,在其中實(shí)現(xiàn)卡片實(shí)例數(shù)據(jù)的刪除。和 JS 卡片相同,需要注意卡片使用方在請求卡片時(shí)傳遞給提供方應(yīng)用的 Intent 數(shù)據(jù)中存在臨時(shí)標(biāo)記字段,表示此次請求的卡片是否為臨時(shí)卡片,由于臨時(shí)卡片的數(shù)據(jù)具有非持久化的特殊性,某些場景比如卡片服務(wù)框架死亡重啟,此時(shí)臨時(shí)卡片數(shù)據(jù)在卡片管理服務(wù)中已經(jīng)刪除,且對應(yīng)的卡片 ID 不會(huì)通知到提供方,所以卡片提供方需要自己負(fù)責(zé)清理長時(shí)間未刪除的臨時(shí)卡片數(shù)據(jù)。同時(shí)對應(yīng)的卡片使用方可能會(huì)將之前請求的臨時(shí)卡片轉(zhuǎn)換為常態(tài)卡片。如果轉(zhuǎn)換成功,卡片提供方也需要對對應(yīng)的臨時(shí)卡片 ID 進(jìn)行處理,把卡片提供方記錄的臨時(shí)卡片數(shù)據(jù)轉(zhuǎn)換為常態(tài)卡片數(shù)據(jù),防止提供方在清理長時(shí)間未刪除的臨時(shí)卡片時(shí),把已經(jīng)轉(zhuǎn)換為常態(tài)卡片的臨時(shí)卡片信息刪除,導(dǎo)致卡片信息丟失。
@Overrideprotected ProviderFormInfo onCreateForm(Intent intent) {long formId = intent.getLongParam(AbilitySlice.PARAM_FORM_ID_KEY, -1L);String formName = intent.getStringParam(AbilitySlice.PARAM_FORM_NAME_KEY);int specificationId = intent.getIntParam(AbilitySlice.PARAM_FORM_DIMENSION_KEY, 0);boolean tempFlag = params.getBooleanParam(AbilitySlice.PARAM_FORM_TEMPORARY_KEY, false);HiLog.info(LABEL_LOG, "onCreateForm: " + formId + " " + formName + " " + specificationId);.......// 將創(chuàng)建的卡片信息持久化,以便在下次獲取/更新該卡片實(shí)例時(shí)進(jìn)行使用,該方法需要由開發(fā)者實(shí)現(xiàn)。storeFormInfo(formId, formName, specificationId, formData);......HiLog.info(LABEL_LOG, "onCreateForm finish.......");return formInfo;}@Overrideprotected void onDeleteForm(long formId) {super.onDeleteForm(formId);// 由開發(fā)人員自行實(shí)現(xiàn),刪除卡片實(shí)例數(shù)據(jù)deleteFormInfo(formId);......}@Overrideprotected void onCastTempForm(long formId) {// 使用方將臨時(shí)卡片轉(zhuǎn)換為常態(tài)卡片觸發(fā),提供方需要做相應(yīng)的處理super.onCastTempForm (formId);......}
④ 卡片數(shù)據(jù)更新
  • 當(dāng)需要卡片提供方更新數(shù)據(jù)時(shí)(如觸發(fā)了定時(shí)更新、定點(diǎn)更新或者卡片使用方主動(dòng)請求更新),卡片提供方獲取最新數(shù)據(jù),并調(diào)用 updateForm 接口更新卡片。示例如下:
@Overrideprotected void onUpdateForm(long formId) {super.onUpdateForm(formId);ComponentProvider componentProvider = new ComponentProvider(ResourceTable.Layout_form_ability_layout_2_2, this);// 獲取卡片實(shí)例需要更新的卡片數(shù)據(jù),需要由開發(fā)者實(shí)現(xiàn)String formData = getUpdateFormData(formId);componentProvider.setText(ResourceTable.Id_title, "update formData-" + formData);updateForm(formId, componentProvider);......}
  • 卡片使用方點(diǎn)擊拉起卡片頁面,會(huì)在 onStart(Intent intent) 中攜帶 formId(通過 AbilitySlice.PARAM_FORM_IDENTITY_KEY 獲取),若需要在 AbilitySlice 中更新,也可以使用 updateForm 接口進(jìn)行更新,示例如下:
public class FormAbilitySlice extends AbilitySlice {......@Overridepublic void onStart(Intent intent) {super.onStart(intent);......Button button = new Button(this);button.setText("Update form data");button.setClickedListener(component -> {......if (intent.hasParameter(AbilitySlice.PARAM_FORM_IDENTITY_KEY)) {int formId = intent.getIntParam(AbilitySlice.PARAM_FORM_ID_KEY, -1);ComponentProvider componentProvider = new ComponentProvider(ResourceTable.Layout_form_ability_layout_2_2, context);String formData = getUpdateFormData(formId);componentProvider.setText(ResourceTable.Id_modifylayout, "update formData-" + formData);getAbility().updateForm(formId, componentProvider);}});......}}
⑤ Java 卡片控制事件
  • Java 卡片當(dāng)前通過 IntentAgent 能力支持對卡片控制設(shè)置事件,例如可以使用 START_ABILITY、START_SERVICE 這兩類能力,在點(diǎn)擊整張卡片時(shí),跳轉(zhuǎn)到提供卡片的 ability。(注:Intent 中支持自定義參數(shù)的傳遞,支持的類型有 int/long/String/List)
  • 示例如下:
@Overrideprotected ProviderFormInfo onCreateForm(Intent intent) {......ProviderFormInfo formInfo = new ProviderFormInfo(ResourceTable.Layout_form_ability_layout_2_2, this);ComponentProvider componentProvider = new ComponentProvider();// 針對title控件設(shè)置事件componentProvider.setIntentAgent(ResourceTable.Id_title, startAbilityIntentAgent());formInfo.mergeActions(componentProvider);......return formInfo;}// 設(shè)置觸發(fā)的事件為系統(tǒng)預(yù)置的HarmonyOS betaApp應(yīng)用private IntentAgent startAbilityIntentAgent() {Intent intent = new Intent();Operation operation = new Intent.OperationBuilder().withDeviceId("").withBundleName("com.huawei.ohos.betaapp.link").withAbilityName("com.huawei.ohos.betaapp.link.MainAbility").build();intent.setOperation(operation);List<Intent> intentList = new ArrayList<>();intentList.add(intent);List<Flags> flags = new ArrayList<>();flags.add(Flags.UPDATE_PRESENT_FLAG);IntentAgentInfo paramsInfo = new IntentAgentInfo(200, IntentAgentConstant.OperationType.START_ABILITY, flags, intentList, null);IntentAgent intentAgent = IntentAgentHelper.getIntentAgent(this, paramsInfo);return intentAgent;}
⑥ 開發(fā) Java 卡片布局
  • 在使用 DevEco Studio 創(chuàng)建模塊時(shí)會(huì)生成對應(yīng)的 Java UI xml 布局文件,需要注意設(shè)置ohos:remote=“true”。
  • 以下是天氣卡片 xml 布局示例,供參考:
<?xml version="1.0" encoding="utf-8"?><DependentLayout xmlns:ohos="http://schemas.huawei.com/res/ohos"ohos:width="match_parent"ohos:height="match_parent"ohos:id="$+id:background"ohos:orientation="vertical"ohos:background_element="$media:weather"ohos:remote="true"><Textohos:id="$+id:title"ohos:text="天氣1"ohos:text_size="39px"ohos:text_color="#b0c4de"ohos:top_margin="42px"ohos:left_margin="20px"ohos:width="match_content"ohos:height="match_content"/><Textohos:id="$+id:temperature"ohos:text="35°"ohos:text_size="100px"ohos:text_color="#b0c4de"ohos:top_margin="25px"ohos:left_margin="20px"ohos:below="$id:title"ohos:width="match_content"ohos:height="match_content"/><Textohos:id="$+id:location"ohos:text="上海"ohos:text_size="39px"ohos:text_color="#b0c4de"ohos:top_margin="24px"ohos:left_margin="20px"ohos:below="$id:temperature"ohos:width="match_content"ohos:height="match_content"/><Textohos:id="$+id:textView4"ohos:text="9月4號 星期五"ohos:text_size="39px"ohos:text_color="#b0c4de"ohos:top_margin="10px"ohos:left_margin="20px"ohos:below="$id:location"ohos:width="match_content"ohos:height="match_content"/><Textohos:id="$+id:textView5"ohos:text="多云"ohos:text_size="39px"ohos:text_color="#b0c4de"ohos:top_margin="10px"ohos:left_margin="150px"ohos:below="$id:location"ohos:end_of="$id:textView4"ohos:align_parent_end="true"ohos:width="match_content"ohos:height="match_content"/><Imageohos:id="$+id:imageView"ohos:width="160px"ohos:height="150px"ohos:top_margin="20px"ohos:left_margin="150px"ohos:below="$id:title"ohos:end_of="$id:temperature"ohos:image_src="$media:clouds"/></DependentLayout>

四、其他可選功能

① 卡片編輯功能
  • 卡片提供方提供一個(gè)卡片的編輯頁面,允許從卡片跳轉(zhuǎn)至編輯頁面。
  • 卡片提供方在配置文件 config.json 中添加參數(shù)“formConfigAbility”,配置參數(shù)信息的規(guī)則如下:
    • 配置該參數(shù)的值,導(dǎo)航到編輯頁面的 Page ability,格式如下:ability://單個(gè)ability名字
    • 如果不配置“formConfigAbility”參數(shù),則無卡片編輯功能。
② 卡片背景模糊
  • 卡片可以在 config.json 中聲明是否支持背景模糊。聲明方式如下:
    config.json 的 metaData 中,在 customizeData 中增加一個(gè) name 為 needBlurBackgroundForLauncher 的字符串類型的屬性,value 為“true”表示支持, 否則為不支持。
"forms": [{"name": "Form_JS_DEMO","description": "it is js form","type": "JS","jsComponentName": "card","colorMode": "auto","isDefault": true,"updateEnabled": true,"scheduledUpdateTime": "10:30","defaultDimension": "2*2","supportDimensions": ["2*2","2*4"],"metaData": {"customizeData": [{"name": "needBlurBackgroundForLauncher","value": "true"}]}}]
  • 卡片開發(fā)者可以從 onCreateForm 的回調(diào)中,獲取是否支持背景模糊:
protected ProviderFormInfo onCreateForm(Intent intent) {......// 1. 獲取自定義數(shù)據(jù)IntentParams intentParams = intent.getParam(AbilitySlice.PARAM_FORM_CUSTOMIZE_KEY);// 2. 從intentParams中獲取是否支持背景模糊boolean isSupport = (boolean) intentParams.getParam("fa_card_background_blur_support");......}
  • 背景模糊限制:
    • 當(dāng)前僅 JS 卡片支持背景模糊;
    • 部分機(jī)型受性能限制,不支持卡片背景模糊。

總結(jié)

以上是生活随笔為你收集整理的HarmonyOS之深入解析服务卡片的使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。