资讯动态

HarmonyOS 多设备短视频开发 : 18 — 侧边栏 SideBarContainer 与分栏交互

发布时间:2026/8/31 10:21:18 来源:尧图企业网站定制
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() { RepeatMSVDataModel(this.data) .each((item: RepeatItemMSVDataModel) { 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 切换页面首页内再嵌套 NavigationContentBuilderBuilder 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; // 小屏半模态 } })SplitCommentproducts/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 单一驱动源 声明式刷新保证侧边栏与内容区联动可靠、无状态漂移。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价