1# 拉起卡片提供方的UIAbility(router事件) 2 3在动态卡片中使用[postCardAction](../reference/apis-arkui/js-apis-postCardAction.md#postcardaction)接口的router能力,能够快速拉起动态卡片提供方应用的指定UIAbility(页面),因此UIAbility较多的应用往往会通过卡片提供不同的跳转按钮,实现一键直达的效果。例如相机卡片,卡片上提供拍照、录像等按钮,点击不同按钮将拉起相机应用的不同UIAbility,从而提高用户的体验。 4 5 6 7> **说明:** 8> 9> 本文主要介绍动态卡片的事件开发。对于静态卡片,请参见[FormLink](../reference/apis-arkui/arkui-ts/ts-container-formlink.md)。 10 11## 开发步骤 121. 创建动态卡片 13 14 在工程的 entry 模块中,新建名为WidgetEventRouterCard的ArkTs卡片。 15 162. 构建ArkTs卡片页面代码布局 17 18 卡片页面布局中有两个按钮,点击其中一个按钮时调用postCardAction向指定UIAbility发送router事件,并在事件内定义需要传递的内容。 19 20 ```ts 21 //src/main/ets/widgeteventroutercard/pages/WidgetEventRouterCard.ets 22 @Entry 23 @Component 24 struct WidgetEventRouterCard { 25 build() { 26 Column() { 27 Text($r('app.string.JumpLabel')) 28 .fontColor('#FFFFFF') 29 .opacity(0.9) 30 .fontSize(14) 31 .margin({ top: '8%', left: '10%' }) 32 Row() { 33 Column() { 34 Button() { 35 Text($r('app.string.ButtonA_label')) 36 .fontColor('#45A6F4') 37 .fontSize(12) 38 } 39 .width(120) 40 .height(32) 41 .margin({ top: '20%' }) 42 .backgroundColor('#FFFFFF') 43 .borderRadius(16) 44 .onClick(() => { 45 postCardAction(this, { 46 action: 'router', 47 abilityName: 'EntryAbility', 48 params: { targetPage: 'funA' } 49 }); 50 }) 51 52 Button() { 53 Text($r('app.string.ButtonB_label')) 54 .fontColor('#45A6F4') 55 .fontSize(12) 56 } 57 .width(120) 58 .height(32) 59 .margin({ top: '8%', bottom: '15vp' }) 60 .backgroundColor('#FFFFFF') 61 .borderRadius(16) 62 .onClick(() => { 63 postCardAction(this, { 64 action: 'router', 65 abilityName: 'EntryAbility', 66 params: { targetPage: 'funB' } 67 }); 68 }) 69 } 70 }.width('100%').height('80%') 71 .justifyContent(FlexAlign.Center) 72 } 73 .width('100%') 74 .height('100%') 75 .alignItems(HorizontalAlign.Start) 76 .backgroundImage($r('app.media.CardEvent')) 77 .backgroundImageSize(ImageSize.Cover) 78 } 79 } 80 ``` 81 824. 处理router事件 83 84 在UIAbility中接收router事件并获取参数,根据传递的params不同,选择拉起不同的页面。 85 86 ```ts 87 //src/main/ets/entryability/EntryAbility.ets 88 import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; 89 import { window } from '@kit.ArkUI'; 90 import { hilog } from '@kit.PerformanceAnalysisKit'; 91 92 const TAG: string = 'EntryAbility'; 93 const DOMAIN_NUMBER: number = 0xFF00; 94 95 export default class EntryAbility extends UIAbility { 96 private selectPage: string = ''; 97 private currentWindowStage: window.WindowStage | null = null; 98 99 onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { 100 // 获取router事件中传递的targetPage参数 101 hilog.info(DOMAIN_NUMBER, TAG, `Ability onCreate: ${JSON.stringify(want?.parameters)}`); 102 if (want?.parameters?.params) { 103 // want.parameters.params 对应 postCardAction() 中 params 内容 104 let params: Record<string, Object> = JSON.parse(want.parameters.params as string); 105 this.selectPage = params.targetPage as string; 106 hilog.info(DOMAIN_NUMBER, TAG, `onCreate selectPage: ${this.selectPage}`); 107 } 108 } 109 110 // 如果UIAbility已在后台运行,在收到Router事件后会触发onNewWant生命周期回调 111 onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void { 112 hilog.info(DOMAIN_NUMBER, TAG, `Ability onNewWant: ${JSON.stringify(want?.parameters)}`); 113 if (want?.parameters?.params) { 114 // want.parameters.params 对应 postCardAction() 中 params 内容 115 let params: Record<string, Object> = JSON.parse(want.parameters.params as string); 116 this.selectPage = params.targetPage as string; 117 hilog.info(DOMAIN_NUMBER, TAG, `onNewWant selectPage: ${this.selectPage}`); 118 } 119 if (this.currentWindowStage !== null) { 120 this.onWindowStageCreate(this.currentWindowStage); 121 } 122 } 123 124 onWindowStageCreate(windowStage: window.WindowStage): void { 125 // Main window is created, set main page for this ability 126 let targetPage: string; 127 // 根据传递的targetPage不同,选择拉起不同的页面 128 switch (this.selectPage) { 129 case 'funA': 130 targetPage = 'pages/FunA'; //与实际的UIAbility页面路径保持一致 131 break; 132 case 'funB': 133 targetPage = 'pages/FunB'; //与实际的UIAbility页面路径保持一致 134 break; 135 default: 136 targetPage = 'pages/Index'; //与实际的UIAbility页面路径保持一致 137 } 138 if (this.currentWindowStage === null) { 139 this.currentWindowStage = windowStage; 140 } 141 windowStage.loadContent(targetPage, (err, data) => { 142 if (err.code) { 143 hilog.error(DOMAIN_NUMBER, TAG, 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); 144 return; 145 } 146 hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); 147 }); 148 } 149 } 150 ``` 1515. 创建跳转后的UIAbility页面 152 153 在pages文件夹下新建FunA.ets和FunB.ets,构建页面布局。 154 155 ```ts 156 //src/main/ets/pages/FunA.ets 157 @Entry 158 @Component 159 struct FunA { 160 @State message: string = 'Hello World'; 161 162 build() { 163 RelativeContainer() { 164 Text(this.message) 165 .id('HelloWorld') 166 .fontSize(50) 167 .fontWeight(FontWeight.Bold) 168 .alignRules({ 169 center: { anchor: '__container__', align: VerticalAlign.Center }, 170 middle: { anchor: '__container__', align: HorizontalAlign.Center } 171 }) 172 } 173 .height('100%') 174 .width('100%') 175 } 176 } 177 ``` 178 1796. 注册UIAbility页面 180 181 打开main_pages.json,将新建的FunA.ets和FunB.ets正确注册在src数组中。 182 ```ts 183 //src/main/resources/base/profile/main_pages.json 184 { 185 "src": [ 186 "pages/Index", 187 "pages/FunA", 188 "pages/FunB" 189 ] 190 } 191 ```