HarmonyOS Next如何实现抽屉式导航效果?

阅读 785
avatarAI BotBETA

HarmonyOS Next 实现抽屉式导航效果,可以通过使用 SideBarContainer 组件来实现。以下是一个基本的实现步骤和示例代码:

实现步骤

  1. 构建 SideBarContainer

    • 使用 SideBarContainer 组件作为容器,该容器包含两个子组件:第一个子组件表示侧边栏,第二个子组件表示内容区。
  2. 设置侧边栏和内容区

    • 在侧边栏中,可以放置导航项的列表(如使用 ColumnForEach 来迭代显示导航项)。
    • 在内容区中,可以放置与当前选中导航项对应的内容。
  3. 配置控制按钮和侧边栏属性

    • 使用 showSideBar 属性来设置是否默认显示侧边栏。
    • 使用 controlButton 属性来配置控制侧边栏展开/收起的按钮样式和位置。
    • 设置 sideBarWidth 来定义侧边栏的宽度。

示例代码

@Entry
@Component
struct SideBarContainerExample {
    @State navList: Array<string> = ["我的会员", "我的收藏", "我的相册", "我的文件"];
    @State isShowingSideBar: boolean = false;

    build() {
        SideBarContainer(SideBarContainerType.Embed) {
            // 侧边栏内容
            Column() {
                ForEach(this.navList, (item) => {
                    ListItem() {
                        Text(item)
                            .width("100%")
                            .fontSize(20)
                            .textAlign(TextAlign.Start)
                            .padding({ top: 20 })
                            .onClick(() => {
                                // 点击列表项时,可以更新状态或执行其他操作
                                this.isShowingSideBar = false; // 关闭侧边栏
                            });
                    }
                })
            }
            .height("100%")
            .padding({ top: 60, left: 50 })
            .backgroundColor("#aabbcc");

            // 内容区
            Column() {
                Text("内容区域")
                    .width("100%")
                    .height("100%")
                    .fontSize(30)
                    .textAlign(TextAlign.Center);
            }
            .width("100%")
            .height("100%")
            .backgroundColor("#bbaacc");
        }
        .showSideBar(false) // 默认不展示侧边栏
        .controlButton({
            left: 10,
            top: 20,
            height: 30,
            width: 30,
            icons: {
                shown: $r('app.media.back'), // 侧边栏展示时图标
                hidden: $r('app.media.sidebar_shown'), // 侧边栏收起时图标
                switching: $r('app.media.sidebar_shown') // 侧边栏切换过程图标
            }
        })
        .sideBarWidth(200)
        .width('100%');
    }
}

注意事项

  • SideBarContainerType.Embed 情况下,真机中内容区域是压缩的,而模拟器中内容区域可能是缺失的。
  • 可以通过切换控制变量(如 isShowingSideBar)来控制侧边栏是否显示,并加入动画效果以提升用户体验。
  • 组件默认不支持手指滑动显示或关闭侧边栏,但可以通过监听内容区的手势事件来自定义实现这一效果。

通过以上步骤和示例代码,你可以在 HarmonyOS Next 应用中实现抽屉式导航效果。

1 个回答
//使用SideBarContainer组件实现侧边导航,并且通过设置该组件的showSideBar控制显示隐藏。在SideBarContainer实现左侧导航样式和右侧内容区。controlButton属性控制侧边导航按钮位置。
// src/main/ets/pages/DrawerTab.ets
SideBarContainer(SideBarContainerType.Overlay) {
  // 左侧导航区域
  Column() {
    // ...
  }
  .height('100%')
  .padding({ top: 104 })
  .backgroundColor('#E9EAEC')
  // src/main/ets/pages/DrawerTab.ets
  // 右侧内容区域
  Column() {
    // ...
  }
  .onClick(() => {
    animateTo({
      duration: Constants.ANIMATION_DURATION,
      curve: Curve.EaseOut,
      playMode: PlayMode.Normal,
    }, () => {
      this.show = false;
    })
  })
  .width('100%')
  .height('110%')
  .backgroundColor(this.show ? '#c1c2c4' : '')
}
.showSideBar(this.show)
.controlButton({
  left: 16,
  top: 48,
  height: 40,
  width: 40,
  icons: {
    shown: $r('app.media.changeBack'),
    hidden: $r('app.media.change'),
    switching: $r('app.media.change')
  }
})
.onChange((value: boolean) => {
  this.show = value;
})
//左侧导航使用Image和Text实现图标加文字的效果。
// src/main/ets/pages/DrawerTab.ets
Column() {
  ForEach(this.navList, (item: number, index: number) => {
    Column() {
      Row() {
        Image(this.active === item ? $r('app.media.activeList') : $r('app.media.list'))
          .width(24)
          .height(24)
        Text($r('app.string.list_name'))
          .fontSize(16)
          .fontColor(Color.Black)
          .fontWeight(FontWeight.Medium)
          .margin({ left: 17 })
      }
      .height(48)
      .width('100%')

      if (this.navList.length - 1 !== index) {
        Row()
          .height(0.5)
          .backgroundColor('#0D000000')
          .width('90%')
      }
    }
    .onClick(() => {
      this.active = item;
    })
    .margin({
      top: 4,
      left:  4,
      right:  4,
      bottom:  4
    })
    .justifyContent(FlexAlign.Center)
    .width(264)
    .height(48)
    .padding({ left: 13})
    .borderRadius(16)
    .backgroundColor(this.active === item ? '#1A0A59F7' : '')
  }, (item: number, index: number) => JSON.stringify(item) + index)

  Row() {
    Image($r('app.media.add'))
      .width(40)
      .height(40)
    Text($r('app.string.add_list')).margin({ left: 8 })
  }
  .width('100%')
  .margin({ top: 284 })
}
.width(272)
.height(344)
.backgroundColor(Color.White)
.borderRadius(20)

本文参与了 【 HarmonyOS NEXT 技术问答冲榜,等你来战!】欢迎正在阅读的你也加入。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进