卡片
1. 卡片概念
- 什么是卡片?
卡片用來顯示或者提示一些基本信息或者進行一些基本操作。注意不能做重邏輯,所有重要邏輯全部交給應用
- 如果是元服務如何喚醒?
因為元服務不提供桌面應用圖標,我們可以通過用戶手動的方式在桌面上添加一張卡片,通過點擊卡片來喚起元服務。
2. 創建卡片
-
在編輯器中創建
-
選擇動態卡片
卡片的特點
:
1.卡片只能承載少量的內容和交互
2. 卡片可以充當元服務icon作為入口,默認提供一張服務卡片作為入口
3. 普通應用也可以添加服務卡片,但默認沒有添加卡片
元服務和普通應用的區別
-
添加卡片
3. ArkTS卡片實現原理
4. ArkTS卡片渲染服務運行原理
5. 卡片的服務通信
5.1 卡片-------> 應用
- 使用postCardAction方法
- 在卡片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'})})}
}
- module.json5添加-保持應用在后臺權限
"requestPermissions": [{"name": "ohos.permission.KEEP_BACKGROUND_RUNNING"}],
- 應用的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');}
}
- 主頁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 應用----------->卡片
- 卡片的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});}
- 卡片:WidgetCard.ets 監聽formId ,當formId發生變化時,發送至應用
@LocalStorageProp("formId")@Watch("updateFormId")formId: string = ""updateFormId () {postCardAction(this, {action: 'call',abilityName: 'EntryAbility', // 只能跳轉到當前應用下的UIAbilityparams: {method: 'updateFormId',formId: this.formId}})}
- 在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()})
- 卸載時解除
onDestroy(): void {this.callee.off("updateNum")this.callee.off("updateFormId")hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');}
- 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}))})}}
- 卡片:從推送的數據中從新獲取
@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'})})}
}
總結:如圖示: