HarmonyOS7 底部操作菜单怎么做:ActionSheetMenuFlow 使用场景与实现思路
文章目录

前言
有些交互不适合用确认框,也不适合跳到新页面。比如一条内容支持“编辑、分享、删除”,你只是想临时给用户一组动作选项,这时候底部操作菜单通常更顺手。
它的特点很明确:不是让用户读长文案,而是让用户在一组操作里快速选一个。这个交互模型和前面的 AlertDialog、CustomDialog 完全不是一个味道。
这一页案例讲的,就是这种轻量操作集合该怎么组织。
这个案例在做什么

页面里有一个“显示操作菜单”按钮,点开后调用 promptAction.showDialog() 展示多项操作。用户选完某一项,页面上的 selectedAction 会同步更新。
也就是说,这页案例的重点是:
- 如何定义一组操作项
- 如何根据点击结果回写页面状态
- 什么场景适合底部操作菜单,而不是确认框
完整代码
import { DEMO_BG_COLOR, DEMO_CARD_COLOR, DEMO_THEME_COLOR } from './types'
import { promptAction } from '@kit.ArkUI'
@Entry
@Component
struct ActionSheetMenuFlow {
@State isShow: boolean = true
@State selectedAction: string = '请选择操作'
build() {
Column() {
if (this.isShow) {
Column() {
Text(`已选择:${this.selectedAction}`)
.fontSize(16)
.fontColor(DEMO_THEME_COLOR)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 20 })
Text('ActionSheet 是从底部弹出的操作菜单,常用于提供一组操作选项。')
.fontSize(14)
.fontColor('#666666')
.margin({ bottom: 24 })
Button('显示操作菜单')
.width('100%').height(48)
.backgroundColor('#4D96FF').borderRadius(12)
.fontColor('#FFFFFF').fontSize(16)
.onClick(() => {
this.showMenu()
})
Column() {
Text('操作说明:')
.fontSize(13).fontColor('#999999').margin({ bottom: 8 })
Text('ActionSheet 适合提供多项操作选择')
.fontSize(12).fontColor('#AAAAAA').margin({ bottom: 4 })
Text('一般从底部滑出,带有取消按钮')
.fontSize(12).fontColor('#AAAAAA').margin({ bottom: 4 })
Text('危险操作(如删除)用红色标识')
.fontSize(12).fontColor('#AAAAAA')
}
.width('100%').margin({ top: 20 }).padding(12)
.backgroundColor('#F8F8F8').borderRadius(8)
}
.width('100%').padding(24).backgroundColor(DEMO_CARD_COLOR).borderRadius(12)
}
Text('ActionSheetMenuFlow - 底部操作菜单')
.fontSize(12).fontColor('#999999').margin({ top: 12 })
}
.width('100%').height('100%').backgroundColor(DEMO_BG_COLOR).padding(16)
}
showMenu() {
promptAction.showDialog({
title: '选择操作',
message: '请选择要执行的操作',
buttons: [
{ text: '编辑', color: '#4D96FF' },
{ text: '分享', color: '#6BCB77' },
{ text: '删除', color: '#FF6B6B' },
{ text: '取消', color: '#999999' }
]
}).then((res) => {
const actions: string[] = ['编辑', '分享', '删除', '已取消']
if (res.index >= 0 && res.index < actions.length) {
this.selectedAction = actions[res.index]
}
})
}
}

为什么这里不用 AlertDialog
因为这不是“请确认一件事”,而是“请从几项动作里选一个”。
这两类交互差别很大。
AlertDialog 更像是暂停你当前动作,要求你确认或取消;底部操作菜单更像是给你一个上下文操作集合,让你快速挑一个继续做。
所以当操作项不止一个,而且都处于并列关系时,底部菜单通常更自然。
selectedAction 是页面反馈出口
案例先定义了:
@State selectedAction: string = '请选择操作'
然后把结果直接展示在页面上:
Text(`已选择:${this.selectedAction}`)
这和前面几篇弹窗教程的思路是一脉相承的。临时浮层里的选择,不应该消失得无影无踪,页面最好有一个清晰反馈点。
promptAction.showDialog() 是这类菜单的入口
真正打开菜单的是:
promptAction.showDialog({
title: '选择操作',
message: '请选择要执行的操作',
buttons: [ ... ]
})
这段配置的核心是 buttons 数组。每一项都代表一个可选动作。
和表单弹窗相比,这种写法非常轻。因为它不需要你自己搭布局结构,适合标准化程度比较高的操作集合。
按钮数组怎么设计更合理
案例定义了四项:
buttons: [
{ text: '编辑', color: '#4D96FF' },
{ text: '分享', color: '#6BCB77' },
{ text: '删除', color: '#FF6B6B' },
{ text: '取消', color: '#999999' }
]
这个顺序和颜色策略都挺典型。
普通操作用常规色,危险操作“删除”单独用红色,取消项放在最后而且弱化显示。这种设计能帮助用户更快理解每个操作的风险等级。
返回结果为什么用索引映射
调用结束后,代码拿到的是结果索引:
.then((res) => {
const actions: string[] = ['编辑', '分享', '删除', '已取消']
if (res.index >= 0 && res.index < actions.length) {
this.selectedAction = actions[res.index]
}
})
这说明 showDialog() 返回的是“点了第几个”,而不是直接给你文案。这样的设计其实很好理解,因为按钮展示文本和业务结果不一定永远一一对应。
实际项目里,你完全可以把这里的映射升级成更正式的动作枚举或行为表。
这种底部菜单最适合的业务场景
内容卡片上的更多操作、文件管理动作、图片处理动作、消息项快捷操作、账户项操作集合,这些都特别适合用操作菜单。
共同点只有一个:用户不需要先读长解释,而是要快速做一个动作选择。
什么时候就不该用它了
如果操作本身风险很高,或者每个选项都需要进一步解释,那就不适合只用一个底部菜单。比如“删除账号”“清空全部记录”这种,最好还是再加一层确认弹窗。
也就是说,操作菜单适合做动作入口,不一定适合直接承担高风险确认。
这个案例下一步可以怎么扩展
后面你可以继续加:
- 根据不同业务对象动态生成菜单项
- 选择后再进入不同二级流程
- 对删除这类危险项加二次确认
- 用枚举或 action key 替代纯文本映射
这些都很常见,而且都能建立在这个最小模型上继续做。
容易踩的坑
第一个坑,是把菜单项写得过多,用户反而一眼看不过来。
第二个坑,是危险动作和普通动作完全不区分颜色和位置。
第三个坑,是拿底部菜单去承载复杂说明,结果像个不完整的弹窗。
写在最后
底部操作菜单的价值,在于把一组并列动作收纳得足够轻、足够快。它不是确认框的替代品,也不是复杂弹窗的缩小版,而是一个非常讲究场景边界的交互组件。
这页案例已经把最小闭环跑通了:定义动作、展示菜单、接住结果。后面再叠业务逻辑,就很自然了。
更多推荐



所有评论(0)