HarmonyOS 鸿蒙Next中Navigation和Tabs底部导航栏问题
HarmonyOS 鸿蒙Next中Navigation和Tabs底部导航栏问题
问题描述
1、父页面跳转子页面后,底部导航栏仍旧显示
代码如下:
父页面 A:
build() {
Column() {
Tabs({
// 确保导航栏在底部
barPosition: BarPosition.End,
controller: this.tabsController
}) {
// 1、记工
TabContent() {
RecordHome()
}
.padding({ left: '12vp', right: '12vp' })
.backgroundColor($r('sys.color.comp_background_gray'))
.tabBar(this.TabBuilder($r('app.string.nav_tab_recordWork'), 0, $r('sys.symbol.doc_plaintext_and_pencil')))
// 2、统计
TabContent() {
RecordHome()
}
.padding({ left: '12vp', right: '12vp' })
.backgroundColor($r('sys.color.comp_background_gray'))
.tabBar(this.TabBuilder($r('app.string.nav_tab_statistics'), 1, $r('sys.symbol.form')))
// 3、社区
TabContent() {
RecordHome()
}
.padding({ left: '12vp', right: '12vp' })
.backgroundColor($r('sys.color.comp_background_gray'))
.tabBar(this.TabBuilder($r('app.string.nav_tab_community'), 2, $r('sys.symbol.ellipsis_message')))
// 4、我的
TabContent() {
RecordHome()
}
.padding({ left: '12vp', right: '12vp' })
.backgroundColor($r('sys.color.comp_background_gray'))
.tabBar(this.TabBuilder($r('app.string.nav_tab_mine'), 3, $r('sys.symbol.person')))
}
.width('100%')
.height('100%')
.barHeight('50vp')
.barMode(BarMode.Fixed)
.onChange((index: number) => {
// 该方法实现双向绑定,以处理非用户点击导致的导航栏变化
this.currentIndex = index;
})
}
.width('100%')
.height('100%')
.backgroundColor($r('sys.color.comp_background_gray'))
}
父页面引用的 B 组件:
build() {
Navigation(this.pageInfos) {
Stack({ alignContent: Alignment.Bottom }) {
Scroll() {
Column() {
// 记工概要
Column() {
// ... 省略
// 记工项
Column() {
ForEach(this.recordWorkVM.getMockData(), (item: RecordWorkModel, index?: number) => {
RecordWorkItem({
recordData: item
}).onClick(() => {
// 跳转记工详情页
this.pageInfos.pushPathByName('recordDetail', item.id);
});
}, (item: RecordWorkModel) => item.id);
}
.padding({ top: $r("app.float.component_interval_s"), bottom: $r("app.float.component_interval_s") });
}
.width('100%')
.margin({ top: $r("app.float.component_interval_s"), bottom: $r("app.float.component_interval_s") })
.padding($r("app.float.component_interval_s"))
.borderRadius($r('app.float.component_radius_primary'))
.backgroundColor(Color.White);
}
.width('100%')
.backgroundColor($r('sys.color.comp_background_gray'))
}
.height('100%')
.scrollBar(BarState.Off)
.edgeEffect(EdgeEffect.Spring);
// 悬浮菜单栏
Button({ type: ButtonType.Circle }) {
SymbolGlyph($r('sys.symbol.plus'))
.fontSize($r('app.float.font_size_title_m'))
.fontWeight(FontWeight.Bold)
.renderingStrategy(SymbolRenderingStrategy.MULTIPLE_COLOR)
.fontColor([$r('sys.color.icon_on_primary'), $r('sys.color.icon_on_secondary')]);
}
.onClick(() => {
})
.width($r("app.float.button_size_m"))
.height($r("app.float.button_size_m"))
.shadow({ radius: 10, color: Color.Gray })
.margin({ bottom: $r('app.float.component_interval_m') })
.backgroundColor($r('app.color.main_color'));
}
.width('100%')
.height('100%')
}
}
详情页 C:
build() {
NavDestination() {
Text(this.recordId);
Button('触发Info错误')
.onClick(() => {
ErrorService.showError(ErrorMode.INFO, $r('app.string.error_base'), this.getUIContext())
});
Button('触发Warn错误')
.onClick(() => {
ErrorService.showError(ErrorMode.WARN, $r('app.string.error_no_data'), this.getUIContext())
});
Button('触发Error错误')
.onClick(() => {
ErrorService.showError(ErrorMode.ERROR, $r('app.string.error_param'))
});
ErrorHandler();
}
.backgroundColor($r('sys.color.comp_background_gray'))
.title($r('app.string.page_element_record_detail'))
.onBackPressed(() => {
// 弹出路由栈栈顶元素
const popDestinationInfo = this.pageInfos.pop();
console.info(`pop 返回值 ${JSON.stringify(popDestinationInfo)}`);
return true;
}).onReady((context: NavDestinationContext) => {
// 获取已有路由堆栈
this.pageInfos = context.pathStack;
})
}
2、通过官方文档:Tabs页面Navigation路由跳转的实现方式
得知,Navigation 要放在 Tabs 外层。如下:
build() {
Column() {
Navigation(this.pageInfos) {
Tabs({
// 确保导航栏在底部
barPosition: BarPosition.End,
controller: this.tabsController
}) {
// 1、记工
TabContent() {
RecordHome()
}
.padding({ left: '12vp', right: '12vp' })
.backgroundColor($r('sys.color.comp_background_gray'))
.tabBar(this.TabBuilder($r('app.string.nav_tab_recordWork'), 0, $r('sys.symbol.doc_plaintext_and_pencil')))
// ... 省略
}
}
}
}
但是首页,底部 Tabs 导航栏布局有问题,距离底部有很大一段距离:
先感谢大佬,希望能解答我的疑惑,谢谢~
更多关于HarmonyOS 鸿蒙Next中Navigation和Tabs底部导航栏问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html
问题是用Tab组件包裹Navigation组件,跳转Navigation子组件并不会影响到外层的Tab组件,还是要Navigation组件包裹tab组件,然后Navigation组件包裹tab组件底部有一块空白的问题,你在Navigation组件加上一个.hideTitleBar(true)属性就可以了,像这样:
Navigation(this.pageStack){
Column() {
Tabs({
barPosition: BarPosition.End,
index: $$this.currentIndex
}) {
ForEach(this.tabList, (tab: string, index: number) => {
TabContent() {
MyPage()
}
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
.tabBar(this.tabBuilder(index, tab))
.onWillShow(() => {
console.log('willshow' + tab)
})
.onWillHide(() => {
console.log('willhide' + tab)
})
})
}
.onChange((index: number) => {
// currentIndex控制TabContent显示页签
this.currentIndex = index;
this.selectedIndex = index;
})
}
.height('100%')
.width('100%')
}
.navDestination(this.pageMap)
.hideTitleBar(true)
更多关于HarmonyOS 鸿蒙Next中Navigation和Tabs底部导航栏问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
确实可以。不过我感觉用navgation作为底部导航栏的实现会更好一点。tabs作为一个页面内部的页签,
在HarmonyOS Next中,Navigation组件用于管理页面导航结构,Tabs组件实现底部导航栏。两者结合时,需通过Navigation的子组件Tabs定义底部栏,并使用NavDestination配置各导航目标页。确保Tabs的barPosition属性设置为底部,并通过TabContent关联对应页面内容。导航状态由NavController管理,切换标签页时自动更新页面栈。
在HarmonyOS Next中,Tabs组件作为Navigation的子组件时,底部导航栏出现间距是常见的布局问题。这是由于Navigation默认会为页面内容预留安全区域,包括状态栏和导航栏区域。
解决方案是在Navigation组件上设置hideTitleBar
属性为true,并手动处理安全区域:
build() {
Column() {
Navigation(this.pageInfos) {
Tabs({
barPosition: BarPosition.End,
controller: this.tabsController
}) {
// TabContent内容...
}
.width('100%')
.height('100%')
.barHeight('50vp')
.barMode(BarMode.Fixed)
}
.hideTitleBar(true) // 隐藏标题栏
.navBarWidth('100%')
.navBarHeight('100%')
}
.width('100%')
.height('100%')
.padding({ bottom: $r('app.float.safe_area_bottom') }) // 适配底部安全区域
}
关键点:
hideTitleBar(true)
移除默认的标题栏占用空间- 通过padding适配底部安全区域,避免内容被遮挡
- 确保Tabs的高度设置为100%以充分利用可用空间
这样调整后,底部Tabs导航栏将正确贴合屏幕底部,同时保持正常的页面跳转行为。