
鸿蒙:Navigation的布局和路由跳转使用方法
我们还是和之前一样,参考官方文档学习,并且将其作为我们实践的依据,链接如下:
如果你已经大致浏览了官方文档中的参数介绍和示例介绍,还是有些小问题,那么可以继续往下看。
- 创建Navigation和NavDestination页面【重点】
- 创建标题栏(title),菜单栏(menus)
- 使用导航控制器实现路由跳转【重点】
1、创建Navigation页面和NavDestination页面:
你可以理解Navigation是父组件,NavDestination是子组件。当然你也可以理解Navigation是根组件。所以,Navigation只有一个即可,NavDestination可以有多个。理解了后我们继续往下。
我们在根页面使用Navigation()组件包裹内容,在需要跳转到的页面使用NavDestination()组件包裹内容。接下来我来做个演示。
Index.ets 【这是根页面,根组件就用Navigation() 】
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
build() {
Navigation() {
Column(){
Button("跳转到PageOne")
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
}
}
}
PageOne.ets 和 PageTwo.ets 是需要跳转的子页面,使用NavDestination()包裹内容
@Component
export struct PageOne {
build() {
NavDestination(){
Column(){
Button("跳转到PageTwo")
}
.height("100%")
.width("100%")
.justifyContent(FlexAlign.Center)
}
}
}
@Component
export struct PageTwo {
build() {
NavDestination(){
Column(){
Button("返回上一页")
}
.height("100%")
.width("100%")
.justifyContent(FlexAlign.Center)
}
}
}
2、创建标题栏(title),菜单栏(menus)
这一步可以根据自己的需要可配可不配,我们直接复制官方示例代码到Index.ets中,然后绑定到Navigation()组件上:
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
@Builder
NavigationTitle() {
Column() {
Text('Title')
.fontColor('#182431')
.fontSize(30)
.lineHeight(41)
.fontWeight(700)
Text('subtitle')
.fontColor('#182431')
.fontSize(14)
.lineHeight(19)
.opacity(0.4)
.margin({ top: 2, bottom: 20 })
}.alignItems(HorizontalAlign.Start)
}
@Builder
NavigationMenus() {
Row() {
Image($r("app.media.startIcon"))
.width(24)
.height(24)
Image($r("app.media.startIcon"))
.width(24)
.height(24)
.margin({ left: 24 })
Image($r("app.media.startIcon"))
.width(24)
.height(24)
.margin({ left: 24 })
}
}
build() {
Navigation() {
Column(){
Button("跳转到PageOne")
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
}
.title(this.NavigationTitle)
.menus(this.NavigationMenus)
}
}
3、使用导航控制器实现路由跳转【重点】
前面主要是通过配置组件,实现页面的正常显示,但是此时并不能跳转,如果想跳转,还需以下步骤:
①在NavDestination()组件包裹的页面,配置跳转组件的Builder函数,格式如下:
@Builder
export function PageOneBuilder(name: string, param: Object) {
PageOne()
}
②设置路由跳转控制器,格式如下:
pageInfos: NavPathStack = new NavPathStack();
注意:要将控制器绑定到Navigation()组件,下面会有代码展示
③注册路由表,在如图所示的目录下注册,格式如下:
cke_2529.png
{
"routerMap": [
{
"name": "pageOne",
"pageSourceFile": "src/main/ets/pages/PageOne.ets",
"buildFunction": "PageOneBuilder",
"data": {
"description": "this is pageOne"
}
},
{
"name": "pageTwo",
"pageSourceFile": "src/main/ets/pages/PageTwo.ets",
"buildFunction": "PageTwoBuilder"
}
]
}
④在module.json5中注册路由表
将我们③步创建的路由表在这里注册下,不然会出现跳转到空白页的情况:
"routerMap": "$profile:route_map",
如果以上看完了,我们就开始实战,项目运行效果和完整代码如下:
cke_5358.png
cke_7602.png
cke_9935.png
Index.ets
export const pageInfos: NavPathStack = new NavPathStack();
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
@Builder
NavigationTitle() {
Column() {
Text('Title')
.fontColor('#182431')
.fontSize(30)
.lineHeight(41)
.fontWeight(700)
Text('subtitle')
.fontColor('#182431')
.fontSize(14)
.lineHeight(19)
.opacity(0.4)
.margin({ top: 2, bottom: 20 })
}.alignItems(HorizontalAlign.Start)
}
@Builder
NavigationMenus() {
Row() {
Image($r("app.media.startIcon"))
.width(24)
.height(24)
Image($r("app.media.startIcon"))
.width(24)
.height(24)
.margin({ left: 24 })
Image($r("app.media.startIcon"))
.width(24)
.height(24)
.margin({ left: 24 })
}
}
build() {
Navigation(pageInfos) {
Column(){
Button("跳转到PageOne")
.onClick(()=>{
pageInfos.pushPath({ name: 'pageOne' });
})
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
}
.title(this.NavigationTitle)
.menus(this.NavigationMenus)
}
}
PageOne.ets
import { pageInfos } from "./Index"
@Builder
export function PageOneBuilder() {
PageOne()
}
@Component
export struct PageOne {
build() {
NavDestination(){
Column(){
Button("跳转到PageTwo")
.onClick(()=>{
pageInfos.pushPath({ name: 'pageTwo' });
})
}
.height("100%")
.width("100%")
.justifyContent(FlexAlign.Center)
}
}
}
PageTwo.ets
import { pageInfos } from "./Index";
@Builder
export function PageTwoBuilder() {
PageTwo()
}
@Component
export struct PageTwo {
build() {
NavDestination(){
Column(){
Button("返回上一页")
.onClick(()=>{
pageInfos.pop()
})
}
.height("100%")
.width("100%")
.justifyContent(FlexAlign.Center)
}
}
}
NavigationDemo\entry\src\main\resources\base\profile\route_map.json
{
"routerMap": [
{
"name": "pageOne",
"pageSourceFile": "src/main/ets/pages/PageOne.ets",
"buildFunction": "PageOneBuilder",
"data": {
"description": "this is pageOne"
}
},
{
"name": "pageTwo",
"pageSourceFile": "src/main/ets/pages/PageTwo.ets",
"buildFunction": "PageTwoBuilder"
}
]
}
NavigationDemo\entry\src\main\module.json5
{
"module": {
"routerMap": "$profile:route_map",
"name": "entry",
"type": "entry",
"description": "$string:module_desc",
"mainElement": "EntryAbility",
"deviceTypes": [
"phone"
],
"deliveryWithInstall": true,
"installationFree": false,
"pages": "$profile:main_pages",
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"description": "$string:EntryAbility_desc",
"icon": "$media:layered_image",
"label": "$string:EntryAbility_label",
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background",
"exported": true,
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"ohos.want.action.home"
]
}
]
}
],
"extensionAbilities": [
{
"name": "EntryBackupAbility",
"srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets",
"type": "backup",
"exported": false,
"metadata": [
{
"name": "ohos.extension.backup",
"resource": "$profile:backup_config"
}
],
}
]
}
}
以上是个人经验分享。
文章来源:https://developer.huawei.com/consumer/cn/blog/topic/03195995279885138
