HarmonyOS Navigation路由组件使用
Navigation可以作为路由组件来使用1、可以实现雷同Android startActivityForResult的功能。
2、可以实现页面生命周期函数的回调监听
一、Navigation 根节点监听页面的显示和隐蔽
可以通过Navigation onNavBarStateChange函数监听当前页面(Navigation根节点)的显示和隐蔽,通过@State注解的字段传递给TabContent组件,让TabContent可以观察页面的显示和隐蔽状态。
@Entry
@Component
struct Index {
@Provide indexPathStack: NavPathStack = new NavPathStack()
//当前选中的下标
@State currentIndex: number = 0
private tabsController: TabsController = new TabsController();
@State onPageResume: boolean = false
aboutToAppear(): void {
console.info('Index aboutToAppear')
}
/**
* 应用前后台显示
*/
onPageShow(): void {
console.info('Index onPageShow')
}
/**
* 应用前后台隐藏
*/
onPageHide(): void {
console.info('Index onPageHide')
}
@Builder
tabBarBuilder(title: string, targetIndex: number, selectIcon: Resource, unSelectIcon: Resource) {
......
}
build() {
Navigation(this.indexPathStack) {
Tabs({ barPosition: BarPosition.End, controller: this.tabsController }) {
TabContent() {
Home()
}
.tabBar(this.tabBarBuilder('首页', 0, $r('app.media.ic_home_on'), $r('app.media.ic_home_off')))
TabContent() {
Mine({ onPageResume: this.onPageResume })
}.tabBar(this.tabBarBuilder('我的', 1, $r('app.media.ic_mine_on'), $r('app.media.ic_mine_off')))
}
.vertical(false)
.divider({ strokeWidth: 0.5, color: '#0D182431' })
.scrollable(false)
.backgroundColor('#F1F3F5')
}
.mode(NavigationMode.Stack)
.hideTitleBar(true)
// .hideToolBar(true)
.backgroundColor("#FFFFFF")
.onNavBarStateChange((isVisible: boolean)=>{
//Navigation组件,根节点如何监听隐藏与展示,监听页面占中的显示和隐藏,上个页面返回的时候会触发,https://www.wzhi.top/?id=25
console.info(`onNavBarStateChange isVisible=${isVisible}`)
this.onPageResume = isVisible
})
}
} 二、Navigation子页面NavDestination实现页面显示隐蔽的监听
Navigation的子页面必要获得栈变量并进行栈的操作,Index.ets的栈变量
@Consume indexPathStack: NavPathStack; 子页面的实现:
@Preview
@Component
export struct Mine {
@State isLogin: boolean = false
@State userInfo: UserInfo = {
avatar: $r('app.media.ic_default_avatar'),
nickname: '未登录'
}
@Consume indexPathStack: NavPathStack;
isFirstShow: boolean = true;
@Prop @Watch('onPageResumeChange') onPageResume: boolean
/**
* 监听页面课件状态,onPageResume 由Index.ets页面传递过来
*/
onPageResumeChange() {
console.info(`Mine onPageResumeChange this.onPageResume=${this.onPageResume}isFirstShow=${this.isFirstShow}`)
if (this.isFirstShow) {
this.isFirstShow = false
return
}
if (this.onPageResume) {
this.getLocalUserInfo()
}
}
/**
* 在创建自定义组件后,执行其build()函数之前执行(NavDestination创建之前),允许在该方法中改变状态变量,更改将在后续执行build()函数中生效。
*/
aboutToAppear(): void {
console.info('mine aboutToAppear')
this.getLocalUserInfo()
}
getLocalUserInfo() {
......
}
build() {
NavDestination() {
Column() {
......
}
.width('100%')
.height('100%')
.backgroundColor('#F5F5F5')
}
.mode(NavDestinationMode.STANDARD)
.hideTitleBar(true)
.onShown(() => {
console.info('Mine onShown')
}).onHidden(() => {
console.info('Mine onHidden')
})
}
@Builder
MenuItem(
icon: Resource,
title: string,
onClick: () => void
) {
......
}
}
可以通过NavDestination的方法.onShown/onHidden监听页面的显示和隐蔽,不过NavDestination是Navigation的跟节点,这个方法就不生效了,比方我再Index.ets中使用了Navigation 嵌套Tabs,TabContent中使用了NavDestination,使用onShown/onHidden就无法被回调,必要在Navigation中使用onNavBarStateChange来监听,把状态传递给TabContent实现页面显示隐蔽的监听。
三、Navigation通过NavPathStack实现页面路由(页面跳转)
1、Navigation实现页面路由,其实是通过NavPathStack的方法来实现的。
可以看到Navigation中传入了参数indexPathStack,类型是NavPathStack,在往下看,是子页面NavDestination接收indexPathStack这个变量来进行页面路由
@Entry
@Component
struct Index {
@Provide indexPathStack: NavPathStack = new NavPathStack()
@Builder
tabBarBuilder(title: string, targetIndex: number, selectIcon: Resource, unSelectIcon: Resource) {
......
}
build() {
Navigation(this.indexPathStack) {
Tabs({ barPosition: BarPosition.End, controller: this.tabsController }) {
......
}
.vertical(false)
.divider({ strokeWidth: 0.5, color: '#0D182431' })
.scrollable(false)
.backgroundColor('#F1F3F5')
}
.mode(NavigationMode.Stack)
.hideTitleBar(true)
// .hideToolBar(true)
.backgroundColor("#FFFFFF")
.onNavBarStateChange((isVisible: boolean)=>{
//Navigation组件,根节点如何监听隐藏与展示,监听页面占中的显示和隐藏,上个页面返回的时候会触发,https://www.wzhi.top/?id=25
console.info(`onNavBarStateChange isVisible=${isVisible}`)
this.onPageResume = isVisible
})
}
} 2、NavDestination接收indexPathStack这个变量来进行页面路
由NavDestination接收indexPathStack这个变量来进行页面路由。
通过 @Consume indexPathStack: NavPathStack 来获取Navigation传递过来的路由栈变量,在onClick中调用this.indexPathStack.pushPathByName 实现页面的跳转。当然参数中的name必要进行配置,接着往下看。
@Preview
@Component
export struct Mine {
@Consume indexPathStack: NavPathStack;
getLocalUserInfo() {
......
}
build() {
NavDestination() {
Column() {
// 顶部用户信息区域
Row() {
Image(this.userInfo.avatar)
.width(80)
.height(80)
.borderRadius(40)
.margin({ right: 20 })
.onClick(() => {
if (!this.isLogin) {
console.info('跳转到登录页面')
this.indexPathStack.pushPathByName('PageLogin', null, true)
}
})
......
}
.width('100%')
.padding(20)
.backgroundColor('#FFFFFF')
}
.margin({ top: 12 })
.backgroundColor('#FFFFFF')
}
.width('100%')
.height('100%')
.backgroundColor('#F5F5F5')
}
.mode(NavDestinationMode.STANDARD)
.hideTitleBar(true)
.onShown(() => {
console.info('Mine onShown')
}).onHidden(() => {
console.info('Mine onHidden')
})
}
@Builder
MenuItem(
icon: Resource,
title: string,
onClick: () => void
) {
......
}
}
3、在src/main/resources/base/profile目录下面创建route_map.json文件,进行路由页面的配置
{
"routerMap": [
{
"name": "PageLogin",//自定义组件的名称
"pageSourceFile": "src/main/ets/components/login.ets",//自定义组件所在的.ets文件的路径
"buildFunction": "PageLoginBuilder",//路由目标页面需要实现这个方法,调用PageLogin(),才能实现最终的路径
"data": {
"description" : "this is Page Login"//当前路由的描述
}
},
{
"name": "RegisterPage",
"pageSourceFile": "src/main/ets/components/register.ets",
"buildFunction": "PageRegisterBuilder",
"data": {
"description" : "this is Page register"
}
},
{
"name": "SettingPage",
"pageSourceFile": "src/main/ets/components/setting.ets",
"buildFunction": "PageSettingBuilder",
"data": {
"description" : "this is Page setting"
}
}
]
} 4、路由目的页面实现,以登录页面为例
// 跳转页面入口函数,路由配置中配置的函数名称
@Builder
export function PageLoginBuilder() {
LoginPage()
}
@Component
struct LoginPage {
@State username: string = ''
@State password: string = ''
@State isLoading: boolean = false
@Consume indexPathStack: NavPathStack
build() {
NavDestination() {
Column() {
}
.width('100%')
.height('100%')
.backgroundColor('#FFFFFF')
}
.hideTitleBar(true)
.onShown( ()=>{//页面显示的监听
console.info('login onShow')
})
.onHidden(()=>{//页面隐藏的监听
console.info('login onHidden')
})
}
private handleLogin() {
......
}
}
完整代码已经上传到gitee:WanHarmony: wanAndroid api 鸿蒙应用
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]