文档管理中心
FAQ应用框架开发UI框架窗口管理子窗口控制主窗口的页面跳转

子窗口控制主窗口的页面跳转

问题现象

页面中有子窗口的场景下,需要通过Router操作主窗口页面,但是调用pushUrl、replaceUrl等方法后,操作的是子窗口的页面,怎么才能获取到主窗口的Router对象操作主窗口的页面?

效果预览

背景知识

  • Router提供通过不同的url访问不同的页面,包括跳转到应用内的指定页面、同应用内的某个页面替换当前页面、返回上一页面或指定的页面等。
  • createSubWindow:可以创建当前WindowStage实例下的子窗口。

解决方案

子窗口和主窗口是两个独立的路由栈,子窗口中使用pushUrlback等方法只能控制子窗口页面的跳转和返回。

若需要在子窗口控制主窗口页面跳转,需要在子窗口中获取到主窗口的路由栈。

  1. 在EntryAbility中的onWindowStageCreate方法中使用AppStorage保存WindowStage实例。
    收起
    自动换行
    深色代码主题
    复制
    1. import { ConfigurationConstant, UIAbility } from '@kit.AbilityKit';
    2. import { hilog } from '@kit.PerformanceAnalysisKit';
    3. import { window } from '@kit.ArkUI';
    4. const DOMAIN = 0x0000;
    5. export default class EntryAbility extends UIAbility {
    6. onCreate(): void {
    7. try {
    8. this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
    9. } catch (err) {
    10. hilog.error(DOMAIN, 'testTag', 'Failed to set colorMode. Cause: %{public}s', JSON.stringify(err));
    11. }
    12. hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
    13. }
    14. onDestroy(): void {
    15. hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');
    16. }
    17. onWindowStageCreate(windowStage: window.WindowStage): void {
    18. // Main window is created, set main page for this ability
    19. hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
    20. // 第一步:通过AppStorage保存WindowStage实例
    21. AppStorage.setOrCreate('windowStage', windowStage);
    22. windowStage.loadContent('pages/SubWindowDemo', (err) => {
    23. if (err.code) {
    24. hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
    25. return;
    26. }
    27. hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
    28. });
    29. }
    30. onWindowStageDestroy(): void {
    31. // Main window is destroyed, release UI related resources
    32. hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
    33. }
    34. onForeground(): void {
    35. // Ability has brought to foreground
    36. hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground');
    37. }
    38. onBackground(): void {
    39. // Ability has back to background
    40. hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground');
    41. }
    42. };
  1. 创建子窗口需要加载的页面SubWindowPage.ets,在该页面中获取WindowStage实例下的主窗口对象,通过getUIContext()获取UIContext实例,再通过getRouter()获取Router对象。
    收起
    自动换行
    深色代码主题
    复制
    1. import { router, window } from '@kit.ArkUI';
    2. @Entry
    3. @Component
    4. struct SubWindowPage {
    5. onBackPress(): boolean | void {
    6. // 侧滑返回首页
    7. let uiContext: UIContext | null = null;
    8. let windowStage = AppStorage.get('windowStage') as window.WindowStage;
    9. // 通过getMainWindowSync获取WindowStage实例下的主窗口
    10. let windowClass: window.Window = windowStage.getMainWindowSync();
    11. uiContext = windowClass.getUIContext();
    12. // 获取Router对象
    13. uiContext.getRouter().pushUrl({
    14. url: 'pages/SubWindowDemo',
    15. }, router.RouterMode.Single);
    16. }
    17. build() {
    18. Column({ space: 10 }) {
    19. Text('子窗口 SubWindow');
    20. Button('主窗口页面跳转')
    21. .onClick(() => {
    22. try {
    23. console.info('主窗口页面跳转');
    24. let uiContext: UIContext | null = null;
    25. let windowStage = AppStorage.get('windowStage') as window.WindowStage;
    26. // 通过getMainWindowSync获取WindowStage实例下的主窗口
    27. let windowClass: window.Window = windowStage.getMainWindowSync();
    28. uiContext = windowClass.getUIContext();
    29. // 获取Router对象
    30. uiContext.getRouter().pushUrl({
    31. url: 'pages/Page', // 需要自行创建一个Page页面
    32. }, router.RouterMode.Single);
    33. } catch (exception) {
    34. console.error(`Failed to create the subwindow. Cause code: ${exception.code}, message: ${exception.message}`);
    35. };
    36. });
    37. }
    38. .borderRadius('16vp')
    39. .backgroundColor('#F1F3F5')
    40. .justifyContent(FlexAlign.Center)
    41. .height('100%')
    42. .width('100%')
    43. }
    44. }
  2. 在SubWindowDemo.ets文件中,创建子窗口,并通过loadContent方法加载步骤2创建的SubWindowPage页面。
    收起
    自动换行
    深色代码主题
    复制
    1. import { display, window } from '@kit.ArkUI';
    2. import { BusinessError } from '@kit.BasicServicesKit';
    3. @Entry
    4. @Component
    5. struct SubWindowDemo {
    6. build() {
    7. Column() {
    8. Button('创建子窗口')
    9. .onClick(() => {
    10. let windowStage = AppStorage.get('windowStage') as window.WindowStage;
    11. try {
    12. windowStage.createSubWindow('mySubWindow').then((windowClass: window.Window) => {
    13. windowClass.loadContent('pages/SubWindowPage', null);
    14. const screenWidth = display.getDefaultDisplaySync().width;
    15. // 子窗口居中
    16. windowClass.moveWindowTo(screenWidth / 2 - this.getUIContext().vp2px(200) / 2, 400);
    17. // 设置子窗口大小
    18. windowClass.resize(this.getUIContext().vp2px(200), this.getUIContext().vp2px(200));
    19. // 展示子窗口
    20. windowClass.showWindow();
    21. console.info(`Succeeded in creating the subwindow. Data: ${JSON.stringify(windowClass)}`);
    22. }).catch((err: BusinessError) => {
    23. console.error(`Failed to create the subwindow. Cause code: ${err.code}, message: ${err.message}`);
    24. });
    25. } catch (exception) {
    26. console.error(`Failed to create the subwindow. Cause code: ${exception.code}, message: ${exception.message}`);
    27. }
    28. })
    29. }
    30. .justifyContent(FlexAlign.Center)
    31. .height('100%')
    32. .width('100%')
    33. }
    34. }
在 FAQ 中进行搜索
请输入您想要搜索的关键词