HarmonyOS 多设备短视频开发 : 18 — 侧边栏 SideBarContainer 与分栏交互
2026/8/31 10:21:17 网站建设 项目流程

18 — 侧边栏 SideBarContainer 与分栏交互

一、引言

PC 与平板宽屏下,"左侧导航 + 右侧内容"是信息密度最高、操作效率最好的信息架构。HarmonyOS 的 SideBarContainer 提供 sidebar/content 双区域布局。本项目 PC 端(products/pc/src/main/ets/view/Index.ets)用它承载主导航与内容区,并在内容区内嵌套 Navigation 实现评论/个人作品的二级分栏,形成"侧边栏 → 页签 → 内容区 → 侧面板"的分层导航体系。本文拆解其实现细节。

二、SideBarContainer 结构与属性

SideBarContainer 的第一个子组件是侧边栏,第二个是内容区:

SideBarContainer(SideBarContainerType.Embed) { Column() { /* 侧边栏:Logo + 菜单列表 */ } Column() { this.ContentBuilder({ index: this.selectedIndex }) } } .sideBarWidth(112) .autoHide(false) .divider({ strokeWidth: 0.5, color: '#ff646466' }) .showControlButton(false)

属性说明本项目取值

sideBarWidth侧边栏宽度112vp 固定
autoHide是否自动隐藏false(常驻)
showControlButton是否显示系统折叠按钮false(自绘菜单)
divider侧栏与内容区分隔线0.5vp 半透明

SideBarContainerType.Embed表示侧边栏嵌入内容区而非悬浮覆盖,内容区宽度实时重排。

三、PC 端侧边栏菜单实现

菜单由 MSVDataModel 数组驱动,Repeat 渲染,选中项高亮:

List() { Repeat<MSVDataModel>(this.data) .each((item: RepeatItem<MSVDataModel>) => { ListItem() { Row({ space: 8 }) { MSVTextIcon({ src: this.selectedIndex === item.index ? item.item.icon : item.item.iconDark, iconSize: 24 }) Text(item.item.text) .fontColor(this.selectedIndex === item.index ? '#ffffff' : '#c7c7c8') } .height(40).borderRadius(8) .backgroundColor(this.selectedIndex === item.index ? $r('app.color.all_icon_bg_10') : Color.Transparent) } .onClick(() => { this.selectedIndex = item.index; }) // 切换内容区 }) .virtualScroll({ totalCount: this.data.length }) }

virtualScroll启用虚拟滚动,长菜单下保证帧率稳定;selectedIndex是内容区刷新的唯一驱动源。

四、内容区与页签联动

内容区根据 selectedIndex 切换页面,首页内再嵌套 Navigation(ContentBuilder):

@Builder ContentBuilder(params: ContentParamsModel) { if (params.index === 0) { Navigation(this.pathStack) { Stack({ alignContent: Alignment.TopEnd }) { recommend() } } .navBarWidthRange(['66%', '100%']) .navBarWidth('66%') .hideBackButton(true) .hideTitleBar(true) .mode(this.showSideComment || this.showSideIndividual ? NavigationMode.Split : NavigationMode.Stack) } else if (params.index === 1) { follow() } else if (params.index === 5) { mine() } }

内容区导航宽度取 '66%',为右侧侧面板预留空间,与 default 产品按断点取固定宽度的策略互补。

五、分栏模式下评论与个人作品的侧面板

打开评论时置 showSideComment = true 并 pushPathByName('SplitComment'),Navigation 自动切 Split 模式,NavDestination 作为右侧面板展开,主内容区不退出:

.onAction(() => { if (this.showSideComment || this.windowInfo.widthBp === WidthBreakpoint.WIDTH_XS) return; if (this.windowInfo.widthBp > WidthBreakpoint.WIDTH_SM) { this.showSideComment = true; this.pathStack.pushPathByName('SplitComment', null); // 大屏:侧面板 } else { this.showComment = true; // 小屏:半模态 } })

SplitComment(products/default/.../view/SplitComment.ets)自定义标题栏,点击关闭时出栈并复位开关:

@Builder CustomTitleBuilder() { Column() { Column().width(CommonConstants.FULL_PERCENT).height(36) .linearGradient({ direction: GradientDirection.Bottom, colors: [['#4D000000', 0.0], ['#00000000', 1.0]] }) Row() { Text($r('app.string.comment_title', this.commentCount)) Row() { SymbolGlyph($r('sys.symbol.xmark')).fontSize(18) } .width(40).aspectRatio(1).borderRadius(CommonConstants.HALF_PERCENT) .onClick(() => { this.pathStack.pop(); this.showSideComment = false; }) } } }

个人作品侧面板同理:showSideIndividual = true 后 pushPathByName('IndividualByRouter', null)。

六、主内容区联动刷新与点击关闭

侧面板打开时主内容区 hitTest 切换为 Block 拦截点击,配合 TapGesture 与 onGestureRecognizerJudgeBegin 实现"点空白收起侧栏":

.hitTestBehavior(this.showSideComment || this.showSideIndividual ? HitTestMode.Block : HitTestMode.Default) .gesture(TapGesture()) .onGestureRecognizerJudgeBegin((event, current) => { if (current && (current.getType() === GestureControl.GestureType.TAP_GESTURE || current.getType() === GestureControl.GestureType.CLICK)) { if (this.showSideComment || this.showSideIndividual) { this.pathStack.pop(); this.showSideComment = false; this.showSideIndividual = false; return GestureJudgeResult.REJECT; } } return GestureJudgeResult.CONTINUE; })

被拦截的点击不会继续透传给视频播放层,避免误触播放/暂停。

七、总结与最佳实践

  • 侧边栏常驻用 autoHide(false) + showControlButton(false),菜单自绘保证全设备视觉一致。
  • 侧面板优先用 Navigation Split 模式而非弹窗,大屏下避免模态割裂、内容上下文不丢失。
  • 断点 + 布尔开关(showSideComment/showSideIndividual)驱动形态:大屏分栏、手机半模态,一套业务逻辑。
  • divider 与选中高亮提升信息层级;virtualScroll 优化长菜单滚动性能。
  • selectedIndex 单一驱动源 + 声明式刷新,保证侧边栏与内容区联动可靠、无状态漂移。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询