HarmonyOS 鸿蒙Next中实现菜单凹陷效果

HarmonyOS 鸿蒙Next中实现菜单凹陷效果 一、需求:

一级分类模块,菜单tab点击效果要求UI实现如下效果:

previewableImage

选中的模块左边两个圆角,右边相邻两个模块分别上一个模块右下角圆角、下一个右上角圆角,做成一个凹陷的效果,想必这样描述很多同学就已经有思路了,可是一开始需求是说做一个凹槽,这样的描述,容易引起开发进入误区,我就是这样,进了死胡同,后来是借鉴了ios的实现方案,才明白描述的重要性,网上的方案是要使用canvas进行路径绘制,太过于麻烦,而且效果不佳,在此我就直接说鸿蒙的实现了,so easy:

二、实现

1.一个列表肯定少不了

build() {

  Row() {

    List({ scroller: this.scroller }) {

      LazyForEach(this.topCategories, (item: HomeCategoryModel, index: number) => {

        ListItem() {

          this.tabBuilder(index, item)

        }
        .backgroundColor(this.currentSelectedClassify !== index ? '#FFFFFF' :
          '#F6F6F6')

      }, (item: HomeCategoryModel, index: number) => JSON.stringify(item) + index)

    }
    .height('100%')
    .width('27.8%')
    .scrollBar(BarState.Off)
    .margin({ top: 10, bottom: this.bottomSafeHeight})
  1. 重点来了
/**
 * 左边侧边栏分类菜单
 * @param index
 * @param name
 */
@Builder
tabBuilder(index: number, item: HomeCategoryModel) {
  RelativeContainer() {
    Text(item.seoTitle)
      .borderRadius({
        topLeft: this.currentSelectedClassify == index && index != 0 ? 8 : 0,
        bottomLeft: this.currentSelectedClassify == index ? 8 : 0,
        topRight: this.currentSelectedClassify + 1 == index ? 8 : 0,
        bottomRight: this.currentSelectedClassify - 1 == index ? 8 : 0
      })
      .width('100%')
      .height(56)
      .fontSize(this.currentSelectedClassify == index ? 16 : 14)
      .fontWeight(this.currentSelectedClassify == index ? FontWeight.Bold : FontWeight.Regular)
      .fontColor('#232323')
      .textAlign(TextAlign.Center)
      .backgroundColor(this.currentSelectedClassify === index ? '#FFFFFF' :
        '#F6F6F6')
      .onClick(() => {
        // TODO:知识点: 3.点击一级列表后,通过一级列表索引获取二级列表索引,分别操作不同的Scroller对象使列表滚动到指定位置
        this.currentSelectedClassify = index;
        this.selectedCategoryId = item.id + ''
        // 请求二级分类接口数据
        this.getSubCategories()

        // 左侧滑动到最后一组时,不需要显示加载更多
        if (this.topCategories.totalCount() - 1 == index) {
          this.isLoadingMore = false
        } else {
          this.isLoadingMore = true
        }

      })
      .id('text')
      .alignRules({
        center: { anchor: '__container__', align: VerticalAlign.Center },
        middle: { anchor: '__container__', align: HorizontalAlign.Center }
      })

    Text()
      .width(5)
      .height(16)
      .backgroundColor('#FE2332')
      .borderRadius({ topRight: 5, bottomRight: 5 })
      .id('red')
      .alignRules({
        center: { anchor: '__container__', align: VerticalAlign.Center },
        left: { anchor: '__container__', align: HorizontalAlign.Start }
      })
      .visibility(this.currentSelectedClassify === index ? Visibility.Visible : Visibility.None)
  }
  .height(56)
}

重要的地方格外注意:

.borderRadius({ topLeft: this.currentSelectedClassify == index && index != 0 ? 8 : 0, bottomLeft: this.currentSelectedClassify == index ? 8 : 0, topRight: this.currentSelectedClassify + 1 == index ? 8 : 0, bottomRight: this.currentSelectedClassify - 1 == index ? 8 : 0 })

  1. 一个很容易忽视的地方,视觉误差,需要提一点:
ListItem() {

  this.tabBuilder(index, item)

}
.backgroundColor(this.currentSelectedClassify !== index ? '#FFFFFF' :
  '#F6F6F6')

结论:这样的思路是不是又简单,代码又清爽呢


更多关于HarmonyOS 鸿蒙Next中实现菜单凹陷效果的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

在HarmonyOS Next中,菜单凹陷效果可通过ArkUI的组件样式与状态管理实现。使用@State装饰器管理菜单项的选中状态,结合条件渲染与样式绑定,为选中项应用特定的视觉样式。例如,通过if或条件样式设置背景色、阴影或边框,以模拟凹陷感。关键是在状态变化时更新样式,确保交互反馈的即时性。

更多关于HarmonyOS 鸿蒙Next中实现菜单凹陷效果的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中实现菜单凹陷效果,你的思路非常清晰且高效。通过动态设置borderRadius的四个角,配合相邻项的圆角处理,确实能简洁地实现这种视觉效果。

你的实现有几个关键点值得肯定:

  1. 条件化圆角设置:通过判断当前选中项索引(currentSelectedClassify)与相邻项的关系,动态设置每个菜单项的四个圆角半径。选中项左侧两个圆角,相邻的上下项分别设置右下角和右上角圆角,形成了自然的凹陷过渡。

  2. 背景色对比:通过为选中项设置白色背景(#FFFFFF),非选中项设置浅灰色背景(#F6F6F6),增强了视觉层次感,使凹陷效果更加明显。

  3. 视觉细节处理:添加了红色指示条(宽度5,高度16,右侧圆角),仅在选中项显示,进一步强化了选中状态。

  4. 性能考虑:使用LazyForEach进行列表渲染,优化了长列表性能。

这种实现方式相比使用Canvas绘制路径更加简洁高效,充分利用了ArkUI的声明式特性和组件化能力。代码逻辑清晰,维护性好,是典型的HarmonyOS Next最佳实践。

对于其他开发者来说,这种思路可以扩展到类似的选项卡、侧边栏导航等场景,通过灵活控制圆角和背景色,实现各种视觉设计效果。

回到顶部