HarmonyOS鸿蒙Next中如何实现页面侧滑显示隐藏菜单功能?

HarmonyOS鸿蒙Next中如何实现页面侧滑显示隐藏菜单功能? 问题描述:鸿蒙应用需要实现侧滑菜单效果,从屏幕左侧滑出菜单页面,点击菜单选项或空白处可关闭菜单,求开发案例和代码

3 回复

**详细回答:**使用鸿蒙的SwipeGesture 手势识别侧滑操作,结合 Stack 布局和状态管理控制菜单的显示与隐藏,通过动画实现滑入滑出效果。定义侧滑手势,监听滑动距离触发菜单显示,使用 Stack 布局叠加主页面和菜单页面,通过 opacity 和translatex控制菜单的显示状态,实现菜气“项点击和空白处点。

✅ 正确做法

/**
 * @author J.query
 * @date 2025/12/25 17:17
 * @email j-query@foxmail.com
 * Description: 侧滑菜单页面,支持从左侧滑出菜单,点击菜单项或空白处关闭菜单
 */

import { StandardTitleBar } from '../components/StandardTitleBar';

@Entry
@Component
struct SlideMenuPage {
  @State isMenuShow: boolean = false
  private menuWidth: number = 280
  private menuOffset: number = 80 // 菜单滑出时主页面偏移量

  build() {
    Stack() {
      // 主页面
      Column() {
        StandardTitleBar({ title: '侧滑菜单示例', onBack: () => {
          // 如果菜单显示,先关闭菜单
          if (this.isMenuShow) {
            this.isMenuShow = false;
          } else {
            // 实际项目中这里可能需要导航回上一页
            console.info('返回上一页');
          }
        }})
        
        Column() {
          Text('主页面内容').fontSize(20)
          
          // 按钮用于手动打开菜单
          Button('打开菜单')
            .margin({ top: 20 })
            .onClick(() => {
              this.isMenuShow = true
            })
          
          // 显示当前菜单状态
          Text(`菜单状态: ${this.isMenuShow ? '显示' : '隐藏'}`)
            .fontSize(16)
            .margin({ top: 20 })
        }
        .width('100%')
        .height('100%')
      }
      .width('100%').height('100%')
      .backgroundColor('#ffffff')
      .translate({ x: this.isMenuShow ? this.menuOffset : 0 }) // 主页面跟随偏移
      .animation({ duration: 300, curve: Curve.EaseInOut })
      
      // 侧滑菜单
      Column() {
        Column() {
          Text('侧滑菜单').fontSize(24).fontWeight(FontWeight.Bold).margin({ top: 60, bottom: 30 })
          
          // 菜单选项列表
          this.MenuItem('首页', 'home')
          this.MenuItem('设备列表', 'device')
          this.MenuItem('数据传输', 'data')
          this.MenuItem('设置', 'setting')
          this.MenuItem('关于', 'about')
          
          // 添加弹性空间使菜单项靠上
          Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start, justifyContent: FlexAlign.Start }) {
          }.flexGrow(1)
        }
        .width(this.menuWidth - 20)
        .padding({ left: 10, right: 10 })
      }
      .width(this.menuWidth)
      .height('100%')
      .backgroundColor('#f8f8f8')
      .borderRadius({ topRight: 20, bottomRight: 20 })
      .translate({ x: this.isMenuShow ? 0 : -this.menuWidth })
      .shadow({ radius: 10, color: '#1f000000', offsetX: 5, offsetY: 0 })
      .animation({ duration: 300, curve: Curve.EaseInOut })
      
      // 遮罩层,用于点击关闭菜单
      if (this.isMenuShow) {
        Column() {
          Blank().backgroundColor('#000000').opacity(0.4)
            .onClick(() => {
              this.isMenuShow = false
            })
        }.width('100%').height('100%')
      }
    }
    .gesture(
      SwipeGesture()
        .onAction(() => {
          // 检测到滑动手势,打开菜单
          if (!this.isMenuShow) {
            this.isMenuShow = true;
          }
        })
    )
  }
  
  // 菜单项组件
  @Builder MenuItem(title: string, icon: string) {
    Row() {
      Text(title)
        .fontSize(18)
        .padding({ top: 15, bottom: 15, left: 10, right: 10 })
        .width('100%')
        .onClick(() => {
          this.handleMenuClick(title);
        })
    }
    .borderRadius(8)
    .backgroundColor('#e0e0e0')
    .margin({ bottom: 10 })
    .hoverEffect(HoverEffect.Auto) // 添加悬停效果
  }
  
  // 处理菜单点击事件
  handleMenuClick(menuTitle: string) {
    console.info(`点击了菜单项: ${menuTitle}`);
    this.isMenuShow = false; // 点击菜单项后关闭菜单
    
    // 根据菜单项执行相应操作
    switch (menuTitle) {
      case '首页':
        // 导航到首页
        break;
      case '设备列表':
        // 导航到设备列表
        break;
      case '数据传输':
        // 导航到数据传输页面
        break;
      case '设置':
        // 导航到设置页面
        break;
      case '关于':
        // 导航到关于页面
        break;
      default:
        break;
    }
  }
}

🎯 效果:

cke_9869.png   cke_16957.png

更多关于HarmonyOS鸿蒙Next中如何实现页面侧滑显示隐藏菜单功能?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,可通过SideBarContainer组件实现侧滑菜单。
主要步骤:

  1. 使用SideBarContainer包裹主内容与侧边栏。
  2. 设置showSideBar属性控制显示/隐藏。
  3. 侧边栏内容自定义,支持滑动触发。
    示例代码片段:
SideBarContainer({  
  showSideBar: this.isShowSideBar  
}) {  
  // 主页面内容  
  Text('主页面')  
  // 侧边栏内容  
  Text('菜单')  
}  

通过手势滑动或按钮切换isShowSideBar状态即可。

在HarmonyOS Next中,可以通过Navigation组件结合NavDestinationdrawer属性,或使用SwipeRow等组件实现侧滑菜单。以下是核心实现思路和代码示例:

方案一:使用Navigation的抽屉菜单(推荐)

这是最标准、最接近原生体验的方式。在NavDestination中配置drawer属性即可快速创建侧滑菜单。

// 1. 定义页面路由
import { Navigation, NavDestination } from '@ohos.router';

@Entry
@Component
struct MainPage {
  build() {
    Navigation() {
      // 主页面内容
      NavDestination({ name: 'home' }) {
        HomePage()
      }
      .title('首页')
      
      // 侧滑菜单页面
      NavDestination({ name: 'menu' }) {
        SideMenu()
      }
      .drawer({ // 关键配置
        position: 'start', // 从左侧滑出
        width: '70%',      // 菜单宽度
        show: false        // 初始隐藏
      })
    }
  }
}

// 2. 侧滑菜单组件
@Component
struct SideMenu {
  build() {
    Column() {
      // 菜单内容
      Text('菜单项1').onClick(() => {
        // 处理点击,可通过路由或状态管理关闭菜单
      })
      Text('菜单项2')
    }
    .width('100%')
    .height('100%')
    .backgroundColor(Color.White)
  }
}

方案二:使用SwipeRow自定义滑动

如果需要更灵活的交互控制,可以使用SwipeRow组件:

@Component
struct SwipeMenuExample {
  @State isMenuVisible: boolean = false
  
  build() {
    // SwipeRow通过滑动手势控制侧边内容显示
    SwipeRow({ 
      side: SideType.Start, // 从左侧滑出
      onGestureSwipe: (isShow: boolean) => {
        this.isMenuVisible = isShow
      }
    }) {
      // 主内容区
      Column() {
        Text('主页面内容')
      }
      .width('100%')
      
      // 侧滑菜单(隐藏在左侧)
      Column() {
        // 菜单内容
      }
      .width('70%')
    }
  }
}

关闭菜单的几种方式:

  1. 点击空白处关闭:在菜单组件外层添加Gesture监听,点击时触发关闭逻辑
  2. 点击菜单项关闭:在菜单项的onClick事件中更新状态或调用路由方法
  3. 编程式控制:通过Navigation的路由API或状态管理控制显示/隐藏

关键注意事项:

  • 使用Navigation方案时,侧滑菜单本身是一个完整的页面(NavDestination),可以独立开发
  • 菜单宽度建议设置为屏幕宽度的60%-80%,确保主内容仍部分可见
  • 滑动灵敏度可通过SwipeRowthreshold参数调整
  • 菜单打开/关闭时可添加转场动画提升体验

这两种方案都能实现标准的Material Design侧滑菜单效果。第一种方案更符合鸿蒙应用架构规范,第二种方案则提供更高的自定义灵活性。

回到顶部