在现代移动应用开发中,页面之间的流畅转场和导航体验是至关重要的。对于 HarmonyOS 开发者来说,Navigation 组件不仅能帮助你实现简单的页面跳转,还支持自定义转场动画、复杂的路由管理以及动态导航堆栈。今天,我们将深入探讨如何使用 HarmonyOS 的 Navigation 组件来实现这些功能。
1. 什么是 Navigation 组件?
Navigation 组件是 HarmonyOS 提供的一个强大工具,用于处理页面之间的跳转和导航管理。通过结合 NavPathStack 和 NavDestination,你可以轻松实现多页面跳转、动态页面堆栈管理、以及自定义页面转场动画,确保你的应用界面流畅且具有良好的用户体验。
1.1 导航转场与路由管理
导航转场是指页面跳转时的动画效果,即当前页面消失,另一个页面显现的过程。Navigation 组件内置了多种转场动画,开发者也可以根据需求自定义动画效果。NavPathStack 组件允许你维护一个动态的路由栈,在页面之间进行灵活的跳转和回退操作。
1.2 结合 NavDestination 实现动态路由
NavDestination 组件负责管理页面之间的跳转和内容展示。你可以在页面中定义不同的导航目标,并在需要时使用 pushPathByName 或 pop 方法来动态管理页面堆栈,支持从当前页面跳转到指定页面或从堆栈中弹出页面返回上一层。
2. 创建导航主页与路由栈
2.1 导航主页的创建
在创建导航主页时,首先需要使用 Navigation 组件来构建页面结构,并通过 NavPathStack 来管理不同页面之间的跳转。以下是一个基本的实现步骤:
@Entry
@Component
struct NavigationDemo {
@Provide('pathInfos') pathInfos: NavPathStack = new NavPathStack();
private listArray: Array<string> = ['WLAN', 'Bluetooth', 'Personal Hotpot', 'Connect & Share'];
build() {
Column() {
Navigation(this.pathInfos) {
TextInput({ placeholder: '输入关键字搜索' })
.width('90%')
.height(40)
.margin({ bottom: 10 })
List({ space: 12, initialIndex: 0 }) {
ForEach(this.listArray, (item: string) => {
ListItem() {
Row() {
Row() {
Text(`${item.slice(0, 1)}`)
.fontColor(Color.White)
.fontSize(14)
.fontWeight(FontWeight.Bold)
}
.width(30)
.height(30)
.backgroundColor('#a8a8a8')
.margin({ right: 20 })
.borderRadius(20)
.justifyContent(FlexAlign.Center)
Column() {
Text(item)
.fontSize(16)
.margin({ bottom: 5 })
}
.alignItems(HorizontalAlign.Start)
Blank()
Row()
.width(12)
.height(12)
.margin({ right: 15 })
.border({
width: { top: 2, right: 2 },
color: 0xcccccc
})
.rotate({ angle: 45 })
}
.borderRadius(15)
.shadow({ radius: 100, color: '#ededed' })
.width('90%')
.alignItems(VerticalAlign.Center)
.padding({ left: 15, top: 15, bottom: 15 })
.backgroundColor(Color.White)
}
.width('100%')
.onClick(() => {
this.pathInfos.pushPathByName(`${item}`, '详情页面参数')
})
}, (item: string): string => item)
}
.listDirection(Axis.Vertical)
.edgeEffect(EdgeEffect.Spring)
.sticky(StickyStyle.Header)
.width('100%')
}
.width('100%')
.mode(NavigationMode.Auto)
.title('设置') // 设置标题文字
}
.size({ width: '100%', height: '100%' })
.backgroundColor(0xf4f4f5)
}
}
2.2 路由跳转的实现
在这个例子中,我们首先创建了一个包含多个导航项的列表,通过点击列表项触发页面跳转。pushPathByName 方法将对应的页面信息推入路由栈,实现页面跳转。
3. 创建导航子页面
3.1 子页面1:CommonPage 的实现
为了展示如何在子页面内进行路由管理,我们使用 NavDestination 组件创建了一个子页面,并通过 NavPathStack 管理页面堆栈。用户可以在子页面内点击按钮返回上一个页面。
@Builder
export function MyCommonPageBuilder(name: string, param: string) {
MyCommonPage({ name: name, value: param })
}
@Component
export struct MyCommonPage {
pathInfos: NavPathStack = new NavPathStack();
name: String = '';
@State value: String = '';
build() {
NavDestination() {
Column() {
Text(`${this.name}设置页面`)
.width('100%')
.fontSize(20)
.fontColor(0x333333)
.textAlign(TextAlign.Center)
.textShadow({
radius: 2,
offsetX: 4,
offsetY: 4,
color: 0x909399
})
.padding({ top: 30 })
Text(`${JSON.stringify(this.value)}`)
.width('100%')
.fontSize(18)
.fontColor(0x666666)
.textAlign(TextAlign.Center)
.padding({ top: 45 })
Button('返回')
.width('50%')
.height(40)
.margin({ top: 50 })
.onClick(() => {
// 弹出路由栈栈顶元素,返回上个页面
this.pathInfos.pop();
})
}
.size({ width: '100%', height: '100%' })
}.title(`${this.name}`)
.onReady((ctx: NavDestinationContext) => {
// 初始化路由堆栈
this.pathInfos = ctx.pathStack;
})
}
}
3.2 子页面2:SharePage 的实现
另一个子页面 MySharePage 展示了如何通过路由堆栈将页面信息推入,并在子页面内管理导航。与 MyCommonPage 类似,SharePage 通过 NavDestination 和 NavPathStack 实现动态的页面跳转。
@Builder
export function MySharePageBuilder(name: string, param: string) {
MySharePage({ name: name })
}
@Component
export struct MySharePage {
pathInfos: NavPathStack = new NavPathStack();
name: String = '';
private listArray: Array<string> = ['Projection', 'Print', 'VPN', 'Private DNS', 'NFC'];
build() {
NavDestination() {
Column() {
List({ space: 12, initialIndex: 0 }) {
ForEach(this.listArray, (item: string) => {
ListItem() {
Row() {
Row() {
Text(`${item.slice(0, 1)}`)
.fontColor(Color.White)
.fontSize(14)
.fontWeight(FontWeight.Bold)
}
.width(30)
.height(30)
.backgroundColor('#a8a8a8')
.margin({ right: 20 })
.borderRadius(20)
.justifyContent(FlexAlign.Center)
Column() {
Text(item)
.fontSize(16)
.margin({ bottom: 5 })
}
.alignItems(HorizontalAlign.Start)
Blank()
Row()
.width(12)
.height(12)
.margin({ right: 15 })
.border({
width: { top: 2, right: 2 },
color: 0xcccccc
})
.rotate({ angle: 45 })
}
.borderRadius(15)
.shadow({ radius: 100, color: '#ededed' })
.width('90%')
.alignItems(VerticalAlign.Center)
.padding({ left: 15, top: 15, bottom: 15 })
.backgroundColor(Color.White)
}
.width('100%')
.onClick(() => {
this.pathInfos.pushPathByName(`${item}`, '页面设置参数')
})
}, (item: string): string => item)
}
.listDirection(Axis.Vertical)
.edgeEffect(EdgeEffect.Spring)
.sticky(StickyStyle.Header)
.width('100%')
}
.size({ width: '100%', height: '100%' })
}.title(`${this.name}`)
.onReady((ctx: NavDestinationContext) => {
this.pathInfos = ctx.pathStack;
})
}
}
-
路由配置
在项目的配置文件 module.json5 中配置路由映射关系,并在 route_map.json 中定义全局路由表:{
"routerMap" : [
{
"name" : "WLAN",
"pageSourceFile" : "src/main/ets/pages/PageOne.ets",
"buildFunction" : "MyCommonPageBuilder"
},
...
]
}
这样,Navigation 组件就能够根据路由表来推送对应的页面,并传递必要的参数。
通过上述实现,我们不仅学会了如何使用 Navigation 和 NavPathStack 组件实现页面跳转,还学会了如何利用 NavDestination 管理页面堆栈,使页面之间的跳转更加灵活和流畅。此外,我们还展示了如何配置路由和自定义页面转场动画,进一步提高了应用的用户体验。
希望这篇博客能帮助你更好地掌握 HarmonyOS 中的导航功能,并应用到你的项目中。如果有任何问题或建议,欢迎在评论区留言!