HarmonyOS鸿蒙Next中使用Navigation全屏跳转到子页面,子页面如何像首页一样分屏?

HarmonyOS鸿蒙Next中使用Navigation全屏跳转到子页面,子页面如何像首页一样分屏?

当前有这么个场景,SplashPage全屏跳转至MainPage,MainPage有分栏,使用Navigation如何实现?

Navigation用于SplashPage, NavDestination用于MainPage,这样就导致了MainPage无法使用分栏;而MainPage使用Navigation,则会导致SplashPage无法跳转至MainPage,请给个详细的例子。

3 回复

最外面的 Navigation 可以通过设置 hideNavBar 为 true 来屏蔽根页面,实现全屏跳转,示例如下:

@Component
struct Index {
  pathStack: NavPathStack = new NavPathStack();

  @Builder
  pagesMap(name: string) {
    if (name == 'SplashPage') {
      SplashPage()
    } else if (name == 'MainPage') {
      MainPage()
    }
  }

  aboutToAppear(): void {
    this.pathStack.pushPath({ name: 'SplashPage' }, false);
    setTimeout(() => {
      this.pathStack.replacePath({ name: 'MainPage' });
    }, 3000);
  }

  build() {
    Navigation(this.pathStack) {
    }.hideNavBar(true)
    .navDestination(this.pagesMap)
  }
}

NavDestination 无法像 Navigation 一样实现双栏,但是可以在 NavDestination 中嵌套一个 Navigation 来实现双栏,示例如下:

@Component
struct MainPage {
  pathStack: NavPathStack | undefined = undefined;
  mainPagePathStack: NavPathStack = new NavPathStack();

  @Builder
  pagesMap(name: string) {
    if (name == 'Plane') {
      Plane()
    } else if (name == 'Train') {
      Train()
    }
  }

  build() {
    NavDestination() {
      // 嵌套一个 Navigation 来实现双栏
      Navigation(this.mainPagePathStack) {
        Button('查看飞机').width('80%').margin({ top: 10, bottom: 10 })
          .onClick(() => {
            this.mainPagePathStack?.pushPath({ name: 'Plane' });
          })
        Button('查看火车').width('80%').margin({ top: 10, bottom: 10 })
          .onClick(() => {
            this.mainPagePathStack?.pushPath({ name: 'Train' });
          })
      }.title('主页面')
      .titleMode(NavigationTitleMode.Mini)
      .navBarWidth('40%')
      .navDestination(this.pagesMap)
    }.hideTitleBar(true)
    .onReady((context: NavDestinationContext) => {
      this.pathStack = context.pathStack;
    })
  }
}

效果如下:

ScreenShot_20250515140109.gif

完整示例如下:

@Component
struct SplashPage {
  pathStack: NavPathStack | undefined = undefined;

  build() {
    NavDestination() {
      Column() {
        Text(`开屏广告`).fontSize(50).fontWeight(2)
      }.width('100%').height('100%').justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)
    }.hideTitleBar(true)
    .onReady((context: NavDestinationContext) => {
      this.pathStack = context.pathStack;
    })
  }
}

@Component
struct Plane {
  pathStack: NavPathStack | undefined = undefined;

  build() {
    NavDestination() {
      Column() {
        Text(`飞机`).fontSize(40).fontWeight(2)
      }.width('100%').height('100%').justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)
    }.hideTitleBar(true)
    .onReady((context: NavDestinationContext) => {
      this.pathStack = context.pathStack;
    })
  }
}

@Component
struct Train {
  pathStack: NavPathStack | undefined = undefined;

  build() {
    NavDestination() {
      Column() {
        Text(`火车`).fontSize(40).fontWeight(2)
      }.width('100%').height('100%').justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)
    }.hideTitleBar(true)
    .onReady((context: NavDestinationContext) => {
      this.pathStack = context.pathStack;
    })
  }
}

@Component
struct MainPage {
  pathStack: NavPathStack | undefined = undefined;
  mainPagePathStack: NavPathStack = new NavPathStack();

  @Builder
  pagesMap(name: string) {
    if (name == 'Plane') {
      Plane()
    } else if (name == 'Train') {
      Train()
    }
  }

  build() {
    NavDestination() {
      // 嵌套一个 Navigation 来实现双栏
      Navigation(this.mainPagePathStack) {
        Button('查看飞机').width('80%').margin({ top: 10, bottom: 10 })
          .onClick(() => {
            this.mainPagePathStack?.pushPath({ name: 'Plane' });
          })
        Button('查看火车').width('80%').margin({ top: 10, bottom: 10 })
          .onClick(() => {
            this.mainPagePathStack?.pushPath({ name: 'Train' });
          })
      }.title('主页面')
      .titleMode(NavigationTitleMode.Mini)
      .navBarWidth('40%')
      .navDestination(this.pagesMap)
    }.hideTitleBar(true)
    .onReady((context: NavDestinationContext) => {
      this.pathStack = context.pathStack;
    })
  }
}

更多关于HarmonyOS鸿蒙Next中使用Navigation全屏跳转到子页面,子页面如何像首页一样分屏?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,使用Navigation全屏跳转到子页面时,若希望子页面像首页一样支持分屏,可以通过在子页面的onPageShow生命周期中调用setDisplayMode方法,将显示模式设置为DisplayMode.SPLIT。同时,确保子页面的布局支持分屏显示,使用SplitLayoutFlexLayout等布局组件。具体实现需根据页面内容和设计需求进行调整。

在HarmonyOS Next中实现SplashPage全屏跳转至分栏MainPage,可以通过以下方式解决:

  1. 推荐方案:使用两级Navigation架构
  • SplashPage使用根Navigation
  • MainPage作为子Navigation容器

示例代码:

// SplashPage.ets
import router from '@ohos.router';

@Entry
@Component
struct SplashPage {
  build() {
    Column() {
      // Splash内容
    }
    .onClick(() => {
      router.replaceUrl({
        url: 'pages/MainPage'
      })
    })
  }
}

// MainPage.ets
@Entry
@Component
struct MainPage {
  @State currentIndex: number = 0;
  
  build() {
    Navigation() {
      Column() {
        // 分栏内容
        Tabs({ barPosition: BarPosition.End }) {
          TabContent() { /* 分页1 */ }
          TabContent() { /* 分页2 */ }
        }
        .onChange((index: number) => {
          this.currentIndex = index;
        })
      }
    }
    .title('主页面')
  }
}
  1. 替代方案:使用单Navigation+条件渲染
// 统一入口页
@Entry
@Component
struct RootPage {
  @State showSplash: boolean = true;

  build() {
    Navigation() {
      if (this.showSplash) {
        // Splash内容
        Column().onClick(() => {
          this.showSplash = false;
        })
      } else {
        // Main分栏内容
        Column() {
          Tabs({ barPosition: BarPosition.End }) {
            TabContent() { /* 分页1 */ }
            TabContent() { /* 分页2 */ }
          }
        }
      }
    }
  }
}

这两种方案都能实现从全屏Splash过渡到分栏MainPage的效果,第一种方案更符合页面路由的常规模式,第二种方案则更简单直接。

回到顶部