ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

HarmonyOS 多设备短视频开发 : 19 — 弹窗体系:半模态、CustomDialog 与提示

2026/8/31 10:07:02 拓冰建站 浏览量
HarmonyOS 多设备短视频开发 : 19 — 弹窗体系:半模态、CustomDialog 与提示 19 — 弹窗体系半模态、CustomDialog 与提示一、引言评论输入、删除确认、轻提示是短视频应用最常见的临时交互。HarmonyOS 提供 bindSheet半模态、CustomDialog自定义弹窗、promptActionToast/对话框三类能力。本项目评论区的手机端形态采用 bindSheet 半模态大屏则切换到 Navigation 分栏形成同一评论组件、多种外壳的弹窗体系。本文结合features/multishortvideocomment/src/main/ets/view/Comment.ets、features/multishortvideoadaptivevideo/src/main/ets/view/AdaptiveVideo.ets讲解选型与实现。二、bindSheet 半模态弹窗半模态从页面底部弹出不脱离内容上下文适合边看边评。视频页在 Swiper 上挂载Local showComment: boolean false; Builder commentContentBuilder() { Comment() } Swiper(this.swiperController) { /* 视频列表 */ } .bindSheet($$this.showComment, this.commentContentBuilder(), { height: CommonConstants.SEVENTY_FIVE_PERCENT, title: { title: $r(app.string.comment_title, 5) }, blurStyle: BlurStyle.Thick, showClose: true })使用要点$$this.showComment双向绑定开关变量状态即显隐height 支持数值/百分比/SheetSize评论取 75%blurStyle 模糊背景视频聚焦内容弹窗内容通过 Builder 传入与 Comment 组件解耦可复用于分栏外壳。三、评论输入条与键盘避让Comment.ets 用 RelativeContainer 将输入条锚定到底部边界、背景、内边距按断点适配Row() { TextInput({ text: this.commentInput!!, placeholder: $r(app.string.leave_comment), controller: this.controller }) .layoutWeight(1) .height(deviceInfo.deviceType tv ? 54 : 40) Row() { MSVTextIcon({ src: ..., iconSize: deviceInfo.deviceType tv ? 32 : 24 }) } .width(deviceInfo.deviceType tv ? 54 : 40) .aspectRatio(1).borderRadius(CommonConstants.HALF_PERCENT) } .alignRules({ bottom: { anchor: __container__, align: VerticalAlign.Bottom }, left: { anchor: __container__, align: HorizontalAlign.Start } }) .padding({ bottom: this.windowInfo.widthBp WidthBreakpoint.WIDTH_SM this.windowInfo.heightBp HeightBreakpoint.HEIGHT_MD ? 0 : new WidthBreakpointTypenumber(28, 28, 28, 28, 0).getValue(this.windowInfo.widthBp) }) .backgroundBlurStyle(this.windowInfo.widthBp WidthBreakpoint.WIDTH_MD ? BlurStyle.BACKGROUND_THIN : BlurStyle.NONE, { scale: 0.5 })键盘弹起时系统自动避让输入条列表底部预留 margin({ bottom: 56 }) 防止最后一条评论被遮挡MD 以上启用毛玻璃小屏关闭保证性能。四、大屏分栏替代半模态手机半模态、大屏分栏是核心策略跳转处按断点分流if (this.windowInfo.widthBp WidthBreakpoint.WIDTH_SM) { this.showSideComment true; this.pathStack.pushPathByName(SplitComment, null); // 大屏分栏侧面板 } else { this.showComment true; // 小屏bindSheet 半模态 }SplitComment 复用同一个 Comment 组件仅外壳不同build() { NavDestination() { Column() { this.CustomTitleBuilder() Comment().height(calc(100% - 92vp)) } } .height(LayoutPolicy.matchParent) .ignoreLayoutSafeArea() .hideTitleBar(true) .backgroundColor(new WidthBreakpointTypeResourceColor($r(sys.color.white), $r(sys.color.white), $r(app.color.bg_dark), $r(app.color.bg_dark)).getValue(this.windowInfo.widthBp)) }五、CustomDialog 与 promptAction 提示确认类操作删除作品等用 CustomDialogCustomDialog struct ConfirmDialog { controller?: CustomDialogController; build() { Column({ space: 16 }) { Text(确认删除该作品) Row() { Button(取消).onClick(() { this.controller?.close(); }) Button(删除).onClick(() { /* 删除逻辑 */ }) } } } }轻量反馈用 promptAction 的 Toastimport { promptAction } from kit.ArkUI; promptAction.showToast({ message: 已发送 });本项目评论主流程以 bindSheet 分栏为主CustomDialog 与 promptAction 服务于确认与反馈类轻量场景。六、多设备弹窗形态差异设备评论形态实现方式手机XS/SM底部半模态bindSheet 75% 高度平板/PCMD右侧分栏面板Navigation Split SplitCommentTV全屏页面NavDestination 全屏 大字手表不提供评论功能裁剪无弹窗七、总结与最佳实践半模态优先用 bindSheet $$ 双向绑定弹窗内容抽成 Builder 以便复用。输入条用 RelativeContainer 锚定底部依赖系统键盘避让并预留列表底部间距。同一评论组件以不同外壳呈现半模态/分栏/全屏断点驱动形态避免三套 UI 代码。确认弹窗用 CustomDialog、轻提示用 promptAction职责单一、调用简单。深色模式与毛玻璃按断点差异化启用兼顾视觉与性能。