HarmonyOS鸿蒙Next中Sidebar侧边栏使用问题
HarmonyOS鸿蒙Next中Sidebar侧边栏使用问题
navigation分栏(整个应用就一个)、tabs和Sidebar怎么一起使用(底部tabs首页可以使用侧边栏,其他没有),
就是做成图一图二那样,图片分别为平板和手机样式,可以给个demo吗?


更多关于HarmonyOS鸿蒙Next中Sidebar侧边栏使用问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html
开发者您好,提供如下demo供参考:
【解决方案】
1、实现Navigation+侧边栏,且分栏效果需要跟随屏幕大小而变化,可以参考示例代码基于一多能力实现响应式布局中的“三分栏”效果; 2、结合Tabs组件,且小屏TabBar在下方,大屏TabBar在左侧;Tabs只有第一个页签需要展示侧边栏,可以修改示例代码中的TripleColumnView文件,修改后如下所示(仅在外层添加Tabs、TabContent组件和vertical属性):
import { WidthBreakpointType } from '../utils/WidthBreakpointType';
import { WindowInfo } from '../utils/WindowUtil';
import { NavigationBarView } from './NavigationBarView';
import { NavigationContent1, NavigationContent2 } from './NavigationContentView';
@Preview
@Component
export struct TripleColumnView {
@ObjectLink @Watch('widthBpChange') mainWindowInfo: WindowInfo;
@State isShowingSidebar: boolean = this.mainWindowInfo.widthBp === WidthBreakpoint.WIDTH_LG ||
this.mainWindowInfo.widthBp === WidthBreakpoint.WIDTH_XL ? true : false;
pageInfos: NavPathStack = new NavPathStack();
pathStack: NavPathStack = new NavPathStack();
widthBpChange(): void {
if (this.mainWindowInfo.widthBp === WidthBreakpoint.WIDTH_LG ||
this.mainWindowInfo.widthBp === WidthBreakpoint.WIDTH_XL) {
this.isShowingSidebar = true;
} else {
this.isShowingSidebar = false;
}
}
@Builder
PageMap(name: string) {
if (name === 'navigationContent1') {
NavigationContent1({
mainWindowInfo: this.mainWindowInfo,
isTripleView: true
})
} else if (name === 'navigationContent2') {
NavigationContent2({ mainWindowInfo: this.mainWindowInfo })
}
}
build() {
Tabs({ barPosition: this.mainWindowInfo.widthBp === WidthBreakpoint.WIDTH_SM ? BarPosition.End : BarPosition.Start }) {
TabContent() {
SideBarContainer(new WidthBreakpointType(SideBarContainerType.Overlay, SideBarContainerType.Overlay,
SideBarContainerType.Embed, SideBarContainerType.Embed).getValue(this.mainWindowInfo.widthBp)) {
Column() {
// [StartExclude triple_column_view]
Image($r('app.media.open_sidebar'))
.width(40)
.height(40)
.onClick(() => {
this.isShowingSidebar = !this.isShowingSidebar;
})
Column() {
Text('SidebarContainer')
.fontSize(18)
.margin({ bottom: 12 })
Text($r('app.string.side_bar'))
.fontSize(24)
}
.width('100%')
.layoutWeight(1)
.justifyContent(FlexAlign.Center)
// [EndExclude triple_column_view]
}
// [StartExclude triple_column_view]
.alignItems(HorizontalAlign.Start)
.backgroundColor('#FFD6B5D6')
.width('100%')
.height('100%')
.padding({
top: this.getUIContext().px2vp(this.mainWindowInfo.AvoidSystem?.topRect.height) + 12,
bottom: this.getUIContext().px2vp(this.mainWindowInfo.AvoidNavigationIndicator?.bottomRect.height),
left: 16,
right: 16
})
// [EndExclude triple_column_view]
Column() {
Navigation(this.pathStack) {
NavigationBarView({
mainWindowInfo: this.mainWindowInfo,
pageInfos: this.pageInfos,
pathStack: this.pathStack,
isShowingSidebar: this.isShowingSidebar,
isTriView: true
})
}
.width('100%')
.height('100%')
.mode(this.mainWindowInfo.widthBp === WidthBreakpoint.WIDTH_SM ? NavigationMode.Stack :
NavigationMode.Split)
.navBarWidth(this.mainWindowInfo.widthBp === WidthBreakpoint.WIDTH_MD ? '50%' : '40%')
.navDestination(this.PageMap)
.backgroundColor('#B8EEB2')
}
// [StartExclude triple_column_view]
.width('100%')
.height('100%')
// [EndExclude triple_column_view]
}
.showSideBar(this.isShowingSidebar)
.sideBarWidth(new WidthBreakpointType('80%', '50%', '20%', '20%').getValue(this.mainWindowInfo.widthBp))
// [End triple_column_view]
.controlButton({ top: this.getUIContext().px2vp(this.mainWindowInfo.AvoidSystem?.topRect.height) + 12 })
.showControlButton(false)
.autoHide(false)
}
.tabBar("首页")
TabContent() {
Text("详情")
}
.tabBar("详情")
TabContent() {
Text("我的")
}
.tabBar("我的")
}
.vertical(this.mainWindowInfo.widthBp === WidthBreakpoint.WIDTH_SM ? false : true)
}
}
上述代码可以实现当检测到小屏时,tabBar在最下方,大屏时设置横向显示tabBar并出现在左侧
更多关于HarmonyOS鸿蒙Next中Sidebar侧边栏使用问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
navigation放在tabs里面,在手机打开二级页面底部tabs还在吧,
开发者您好,以上提供demo中进入“三分栏”后,tabs会一直存在的,如果跟您的需求不符,请提供以下信息:具体的业务场景以及目前提供的demo与期望有哪些不符。
参考我的华为APP布局(除了多了个左右分栏布局),
import { HdsSideMenu, HdsSideMenuMainItem, HdsSideMenuSubItem, HdsSideMenuBadgeParam, HdsSideBar } from '@kit.UIDesignKit';
import { SymbolGlyphModifier } from '@kit.ArkUI';
@Entry
@ComponentV2
struct Index {
@Local showControlButton: boolean = true;
@Local sideBarMask: boolean = false;
@Local autoHide: boolean = true;
@Local barStateTypeText: string = "Select BarState";
@Local widthIndex: number = 0;
@Local badgeNumber: HdsSideMenuBadgeParam = { count: 50 };
@Local useTheme: boolean = false;
@Local selectedIndex: number = 2;
@Local selectedTransparency: number = 0.6;
@Local str: string = "短信";
@Local isShowSidebar: boolean = true;
listOptionsDefault?: HdsSideMenuMainItem[] = [
new HdsSideMenuMainItem(
{
symbol: new SymbolGlyphModifier($r('sys.symbol.ohos_folder_badge_plus')).fontSize(14),
label: $r('sys.string.TextView_engr_phone'),
}),
new HdsSideMenuMainItem({
icon: $r('sys.symbol.person_wave_3'),
label: 'Tuesday',
hdsSideMenuSubItem: [
new HdsSideMenuSubItem({ label: this.str, badge: this.badgeNumber })],
}),
new HdsSideMenuMainItem({
symbol: new SymbolGlyphModifier($r('sys.symbol.person_crop_circle_fill_1')),
label: 'Wednesday',
}),
]
@Builder
SideBarPanelBuilder() {
Column() {
HdsSideMenu({
items: this.listOptionsDefault,
selectedIndex: this.selectedIndex,
$selectedIndex: (selectedIndex: number) => {
this.selectedIndex = selectedIndex;
},
})
}
.height('100%')
}
//右侧内容区
@Builder
ContentPanelBuilder() {
Column() {
Column() {
Button() {
SymbolGlyph(this.isShowSidebar ? $r('sys.symbol.open_sidebar') : $r('sys.symbol.close_sidebar'))
.fontWeight(FontWeight.Normal)
.fontSize($r('sys.float.ohos_id_text_size_headline7'))
.fontColor([$r('sys.color.ohos_id_color_titlebar_icon')])
.hitTestBehavior(HitTestMode.None)
}
.backgroundColor($r('sys.color.ohos_id_color_button_normal'))
.height(24)
.width(24)
.animation({ curve: Curve.Sharp, duration: 100 })
.onClick(() => {
this.isShowSidebar = !this.isShowSidebar;
})
}
}
.height('100%')
.width('100%')
}
@BuilderParam sideBarBuilder: () => void = this.SideBarPanelBuilder
@BuilderParam contentBuilder: () => void = this.ContentPanelBuilder
@Builder
build() {
Column() {
HdsSideBar({
sideBarPanelBuilder: (): void => {
this.sideBarBuilder()
},
contentPanelBuilder: (): void => {
this.contentBuilder()
},
isShowSideBar: this.isShowSidebar,
$isShowSideBar: (isShowSidebar: boolean) => {
this.isShowSidebar = !isShowSidebar
},
})
}
}
}
首先:版本需要从6.0.0(20) Beta1及以上,HdsSideMenu提供一种菜单栏样式组件。设置侧边栏对应的一级菜单和二级菜单,并显示其新消息数量。 参考:侧边栏菜单样式-UI Design Kit(UI设计套件)-应用框架 - 华为HarmonyOS开发者或者侧边栏样式-UI Design Kit(UI设计套件)-应用框架 - 华为HarmonyOS开发者
HarmonyOS Next中Sidebar侧边栏通过@Entry、@Component装饰的组件构建。使用SidebarContainer接口创建容器,通过sidebar参数设置侧边栏内容,content参数设置主内容。侧边栏可控制显示/隐藏,支持通过手势或按钮触发。其宽度可自适应调整,并提供了controlButton属性用于自定义控制按钮。开发者需在aboutToAppear生命周期中初始化侧边栏状态。
在HarmonyOS Next中实现你描述的布局(全局navigation分栏 + 底部tabs + 仅首页支持Sidebar侧边栏),核心思路是采用组合式导航结构,并动态控制Sidebar的显示。以下是一个关键代码示例和实现逻辑:
1. 整体架构设计
使用 NavDestinationStack 作为根容器管理全局分栏,内部嵌套 Tabs 组件实现底部页签,在首页的页面组件中条件渲染 SidebarContainer。
2. 示例代码框架
// 主入口:组合导航结构
@Entry
@Component
struct MainPage {
@State currentTab: number = 0
build() {
NavDestinationStack() {
// 第一栏:带Tab和Sidebar的主界面
NavDestination() {
HomeTabPage({ currentTab: $currentTab }) // 首页Tab容器
}
.title('首页')
// 第二栏:其他分栏页面(无需Sidebar)
NavDestination() {
OtherColumnPage()
}
.title('其他')
}
.mode(NavigationMode.Split)
}
}
// 首页Tab容器
@Component
struct HomeTabPage {
@Link currentTab: number
@State showSidebar: boolean = false // 控制侧边栏显示
build() {
Tabs({ barPosition: BarPosition.End, index: this.currentTab }) {
// 首页Tab:包含Sidebar
TabContent() {
Column() {
// 内容区
Text('首页内容')
Button('开关侧边栏')
.onClick(() => { this.showSidebar = !this.showSidebar })
}
// 条件渲染侧边栏(仅当前Tab为首页时生效)
if (this.showSidebar && this.currentTab === 0) {
SidebarContainer({ sideBarWidth: 240, showSideBar: this.showSidebar }) {
// 侧边栏内容
SideBar()
// 主内容区
MainContent()
}
.onChange((show: boolean) => { this.showSidebar = show })
}
}
.tabBar('首页')
// 其他Tab页(无Sidebar)
TabContent() {
Text('其他页面')
}
.tabBar('发现')
}
}
}
// 侧边栏组件
@Component
struct SideBar {
build() {
Column() {
Text('侧边栏菜单1')
Text('侧边栏菜单2')
}
}
}
3. 关键控制逻辑
- Sidebar显示控制:通过
showSidebar状态变量和条件渲染实现,确保仅在首页Tab激活时可能显示。 - 设备适配:可在
aboutToAppear中通过display.getDefaultDisplaySync()获取设备信息,动态调整sideBarWidth或切换显示模式。 - 导航联动:当切换至非首页Tab时,自动关闭Sidebar(通过监听
currentTab变化重置showSidebar状态)。
4. 注意事项
- 避免在多个TabContent中同时声明Sidebar,防止渲染冲突。
- 平板模式下Navigation分栏宽度可能影响Sidebar显示,需通过
minContentWidth调整布局断点。 - 侧边栏交互状态(如展开/收起)建议使用
AppStorage管理,实现跨组件状态同步。
这种设计实现了分栏导航、底部Tab和条件化侧边栏的分离管理,符合HarmonyOS Next的声明式开发范式。实际开发中需根据具体UI规范调整尺寸和交互细节。

