生活随笔
收集整理的這篇文章主要介紹了
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卡片支持的版本 實(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、DependentLayout div、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ù)雜的頁面和事件。 對于同一個(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è)文件夾的作用: 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ù)字、字母和下劃線。 Select Ability/New Ability:選擇一個(gè)掛靠服務(wù)卡片的 Page Ability,或者創(chuàng)建一個(gè)新的 Page Ability; 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
: "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" } ] } } ]
“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ù) 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
) { super . onDeleteForm ( formId
) ; . . . . . . } @ Overrideprotected
void onUpdateForm ( long formId
) { super . onUpdateForm ( formId
) ; . . . . . . } @ Overrideprotected
void onTriggerFormEvent ( long formId
, String message
) { super . onTriggerFormEvent ( formId
, message
) ; . . . . . . } @ Overrideprotected
void onCastTempForm ( long formId
) { super . onCastTempForm ( formId
) ; . . . . . . } @ Overrideprotected
void onEventNotify ( Map
< Long
, Integer
> formEvents
) { 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 ( ) ) ; } @ 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
) { super . onDeleteForm ( formId
) ; . . . . . . } @ Overrideprotected
void onUpdateForm ( long formId
) { super . onUpdateForm ( formId
) ; . . . . . . } @ Overrideprotected
void onTriggerFormEvent ( long formId
, String message
) { super . onTriggerFormEvent ( formId
, message
) ; . . . . . . } @ Overrideprotected
void onCastTempForm ( long formId
) { super . onCastTempForm ( formId
) ; . . . . . . } @ Overrideprotected
void onEventNotify ( Map
< Long
, Integer
> formEvents
) { 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
) ; . . . . . . . storeFormInfo ( formId
, formName
, specificationId
, formData
) ; . . . . . . HiLog
. info ( LABEL_LOG
, "onCreateForm finish......." ) ; return formInfo
; } @ Overrideprotected
void onDeleteForm ( long formId
) { super . onDeleteForm ( formId
) ; deleteFormInfo ( formId
) ; . . . . . . } @ Overrideprotected
void onCastTempForm ( long formId
) { 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
) ; if ( ! updateForm ( formId
, formBindingData
) ) { } }
開發(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)擊事件。 在 hml 中為組件設(shè)置 onclick 屬性,其值對應(yīng)到 json 文件的 actions 字段中。 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
:
使用該 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
>
@ 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
) ; ZSONObject zsonObject
= new
ZSONObject ( ) ; zsonObject
. put ( "imageSrc" , "memory
: FormBindingData formBindingData
= new
FormBindingData ( zsonObject
) ; formBindingData
. addImageData ( "logo.png" , bytes
) ; 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
: "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
) ; IntentParams intentParams
= intent
. getParam ( AbilitySlice
. PARAM_FORM_CUSTOMIZE_KEY
) ; HiLog
. info ( LABEL_LOG
, "onCreateForm: " + formId
+ " " + formName
+ " " + specificationId
) ; 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
) ; deleteFormInfo ( formId
) ; . . . . . . } @ Overrideprotected
void onUpdateForm ( long formId
) { super . onUpdateForm ( formId
) ; . . . . . . } @ Overrideprotected
void onCastTempForm ( long formId
) { super . onCastTempForm ( formId
) ; . . . . . . } @ Overrideprotected
void onEventNotify ( Map
< Long
, Integer
> formEvents
) { 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
) ; . . . . . . . storeFormInfo ( formId
, formName
, specificationId
, formData
) ; . . . . . . HiLog
. info ( LABEL_LOG
, "onCreateForm finish......." ) ; return formInfo
; } @ Overrideprotected
void onDeleteForm ( long formId
) { super . onDeleteForm ( formId
) ; deleteFormInfo ( formId
) ; . . . . . . } @ Overrideprotected
void onCastTempForm ( long formId
) { 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
) ; 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 ( ) ; componentProvider
. setIntentAgent ( ResourceTable
. Id_title
, startAbilityIntentAgent ( ) ) ; formInfo
. mergeActions ( componentProvider
) ; . . . . . . return formInfo
; } 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
: 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
) { . . . . . . IntentParams intentParams
= intent
. getParam ( AbilitySlice
. PARAM_FORM_CUSTOMIZE_KEY
) ; boolean isSupport
= ( boolean
) intentParams
. getParam ( "fa_card_background_blur_support" ) ; . . . . . . }
總結(jié)
以上是生活随笔 為你收集整理的HarmonyOS之深入解析服务卡片的使用 的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔 推薦給好友。