
文章目录前言工具栏设计原则MenuBar 基础Toolbar 配置菜单项交互图标与文字搭配多级菜单写在最后前言一个 App 用起来爽不爽很大程度取决于操作区设计得好不好。顶部菜单栏放什么操作底部工具栏怎么排列这些细节直接影响用户的操作效率。HarmonyOS7 给我们提供了 MenuBar 和 Toolbar 两套组件一个管菜单一个管工具栏搭配起来用效果拔群。之前做工具类 App每次到了操作区设计就头疼。手写一堆按钮排列状态管理乱七八糟多级菜单更是一团糟。后来发现 ArkUI 自带 ToolBar 组件和 Menu 组件直接省掉了大半工作量。这玩意儿用对了操作区设计可以很优雅。工具栏设计原则在写代码之前先聊聊设计。工具栏不是按钮堆砌得讲究方法高频操作放底部——用户单手够得到的地方才是黄金位置5 个入口是上限——超过就收纳到更多里别让界面太挤图标文字双保险——纯图标容易猜错含义加上文字就清晰了状态即反馈——禁用的灰掉、激活的高亮别让用户猜MenuBar 基础MenuBar 一般放在页面顶部承载文件、编辑这类菜单操作。配合 Menu 组件使用实现下来很直观。EntryComponentstruct MenuBarDemo{StateselectedMenu:string无build(){Column(){Row(){Text(文件).fontSize(14).padding({left:12,right:12,top:8,bottom:8}).bindMenu([{value:新建,action:(){this.selectedMenu新建}},{value:打开,action:(){this.selectedMenu打开}},{value:保存,action:(){this.selectedMenu保存}}])Text(编辑).fontSize(14).padding({left:12,right:12,top:8,bottom:8}).bindMenu([{value:撤销,action:(){this.selectedMenu撤销}},{value:重做,action:(){this.selectedMenu重做}}])}.width(100%).height(48).backgroundColor(#F1F3F5).justifyContent(FlexAlign.Start)Text(当前选择:${this.selectedMenu}).margin({top:40}).fontSize(16)}.width(100%).height(100%)}}逐行讲解bindMenu是关键方法——它把一个 Menu 绑定到任意组件上点击组件就弹出菜单value是菜单项的显示文字action是点击回调顶部 Row 充当菜单栏容器横向排列各个菜单入口用State selectedMenu追踪当前选择实时更新显示Toolbar 配置Toolbar 是底部工具栏组件自动处理超量项的收纳。超过 5 个入口时多余的自动收进更多子项。import{ToolBar,ToolBarOptions,ItemState}fromkit.ArkUIEntryComponentstruct ToolbarDemo{StatetoolbarList:ToolBarOptionsnewToolBarOptions()aboutToAppear(){this.toolbarList.push({content:收藏,icon:$r(sys.media.ohos_ic_public_favor),action:(){console.info(收藏)}})this.toolbarList.push({content:复制,icon:$r(sys.media.ohos_ic_public_copy),action:(){console.info(复制)},state:ItemState.DISABLE})this.toolbarList.push({content:粘贴,icon:$r(sys.media.ohos_ic_public_paste),action:(){console.info(粘贴)},state:ItemState.ACTIVATE})this.toolbarList.push({content:全选,icon:$r(sys.media.ohos_ic_public_select_all),action:(){console.info(全选)}})this.toolbarList.push({content:分享,icon:$r(sys.media.ohos_ic_public_share),action:(){console.info(分享)}})this.toolbarList.push({content:删除,icon:$r(sys.media.ohos_ic_public_remove),action:(){console.info(删除)}})}build(){Stack({alignContent:Alignment.Bottom}){Column(){Text(内容区域).fontSize(20)}.width(100%).height(100%).justifyContent(FlexAlign.Center)ToolBar({toolBarList:this.toolbarList,activateIndex:2})}.width(100%).height(100%)}}关键点讲解ToolBarOptions是工具栏数据模型用push逐个添加菜单项每个项有三个核心属性content文字、icon图标、action点击回调state控制按钮状态ENABLE正常可点、DISABLE灰色不可点、ACTIVATE高亮激活activateIndex指定默认激活项的索引第 6 项删除会自动收进更多菜单不需要你额外处理菜单项交互点击菜单项后的交互逻辑可以直接在action回调里写EntryComponentstruct MenuInteractionDemo{Stateitems:string[][项目A,项目B,项目C]StatetoolbarList:ToolBarOptionsnewToolBarOptions()aboutToAppear(){this.toolbarList.push({content:添加,icon:$r(sys.media.ohos_ic_public_add),action:(){this.items.push(项目${this.items.length1})}})this.toolbarList.push({content:清空,icon:$r(sys.media.ohos_ic_public_remove),action:(){this.items[]}})}build(){Stack({alignContent:Alignment.Bottom}){List(){ForEach(this.items,(item:string){ListItem(){Text(item).fontSize(16).padding(12)}})}.width(100%)ToolBar({toolBarList:this.toolbarList})}.width(100%).height(100%)}}这里把工具栏操作和列表数据联动起来了——点添加就追加项目点清空就全删。因为items是State修饰的数据变化会自动驱动 UI 刷新。图标与文字搭配系统预置了一波图标资源用$r(sys.media.xxx)就能引用。常用图标图标引用用途ohos_ic_public_copy复制ohos_ic_public_paste粘贴ohos_ic_public_share分享ohos_ic_public_favor收藏ohos_ic_public_add添加ohos_ic_public_remove删除ohos_ic_public_select_all全选建议能用系统图标就用系统的风格统一还省资源。如果系统图标不满足需求再用自定义图标放在resources目录下。多级菜单有些场景需要嵌套菜单比如新建下面再分新建文档、“新建表格”。bindMenu支持这种结构Text(文件).fontSize(14).padding(12).bindMenu([{value:新建,action:(){}},{value:新建文档,icon:$r(sys.media.ohos_ic_public_add),action:(){console.info(新建文档)}},{value:导出,action:(){}},{value:导出为PDF,action:(){console.info(导出PDF)}},{value:导出为图片,action:(){console.info(导出图片)}}])血泪教训多级菜单别超过 3 层不然用户找选项找到崩溃。菜单层级越深操作效率越低。如果需要更复杂的菜单交互可以配合CustomDialog自己画菜单面板灵活度更高。写在最后MenuBar 和 Toolbar 各有分工——顶部菜单栏放低频但分类多的操作底部工具栏放高频操作。两者搭配使用操作区的用户体验直接拉满。我觉得 Toolbar 最贴心的设计就是自动收纳超量项。你不用操心按钮太多了怎么办组件帮你搞定。省心。如果你正在做工具类或内容编辑类 App这套组合真的值得试试。代码不多效果很好。