HarmonyOS鸿蒙Next中NavigationView实现菜单页面

HarmonyOS鸿蒙Next中NavigationView实现菜单页面

NavigationView 实现菜单页面

1.添加Material库,和圆形化图片的依赖:

implementation("com.google.android.material:material:1.12.0")
    implementation("de.hdodenhof:circleimageview:3.0.1")

2.引入Material,最好把主题改成Theme.MaterialComponents.Light.NoActionBar

3.准备好headerLayout和menu,并且在Navigation中使用

//这个是header的圆形图片用法
<de.hdodenhof.circleimageview.CircleImageView
    android:id="@+id/iconImage"
    android:layout_height="70dp"
    android:layout_width="70dp"
    android:src="@drawable/nav_icon"
    android:layout_centerInParent="true"//用的相对布局
    />
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
    <item
        android:id="@+id/navCall"
        android:icon="@drawable/nav_call"
        android:title="Call"
        />
    <item
        android:id="@+id/navFriends"
        android:icon="@drawable/nav_friends"
        android:title="Friends"
        />
    <item
        android:id="@+id/navLocation"
        android:icon="@drawable/nav_location"
        android:title="Location"
        />
    <item
        android:id="@+id/navMail"
        android:icon="@drawable/nav_mail"
        android:title="Mail"
        />
    <item
        android:id="@+id/navTask"
        android:icon="@drawable/nav_task"
        android:title="Task"
        />

</group>
</menu>

​ menu中内嵌了一个group,android:checkableBehavior="single"指定了菜单项只能单选

<com.google.android.material.navigation.NavigationView
    android:id="@+id/navView"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:layout_gravity="start"
    app:menu="@menu/nav_menu"
    app:headerLayout="@layout/nav_header"
    />

4.设置菜单的点击事件

binding.navView.setCheckedItem(R.id.navCall)//设置默认选中的菜单项
binding.navView.setNavigationItemSelectedListener {
   item->when(item.itemId){
       R.id.navCall->Toast.makeText(this,"You click Call",Toast.LENGTH_SHORT).show()
    else->Toast.makeText(this,"You Click other",Toast.LENGTH_SHORT).show()
   }
    binding.drawerLayout.closeDrawers()//关闭滑动菜单
    true    //由于按钮可以被多个监听器监听,true表示该点击事件已经被处理,其他监听器不需要再处理了
}

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

3 回复

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


在HarmonyOS Next中,NavigationView组件用于创建导航菜单页面。它通常作为侧边栏或顶部导航栏,管理应用内多个页面的切换。开发者通过定义NavigationView的布局结构,可以添加菜单项并绑定点击事件,实现页面间的导航逻辑。该组件支持自定义样式和交互行为,以适配应用的整体设计。

你提供的代码是Android平台上使用Material Design库中NavigationView的实现方式,但这不适用于HarmonyOS Next

HarmonyOS Next使用全新的ArkUI框架进行声明式开发,其UI组件和API与Android完全不同。在HarmonyOS Next中,实现侧边栏导航菜单的标准方式是使用Navigation组件结合SideBarContainer,或者使用Tabs组件配合侧边布局。

以下是HarmonyOS Next中实现类似功能的核心思路和代码示例:

1. 使用SideBarContainer实现侧边栏菜单

SideBarContainer是HarmonyOS中专门用于创建侧边栏布局的容器组件。

// 示例:SideBarContainer实现
@Entry
@Component
struct SideBarExample {
  @State isSideBarVisible: boolean = true; // 控制侧边栏显示
  @State selectedIndex: number = 0; // 当前选中项

  // 菜单项数据
  private menuItems: Array<string> = ['Call', 'Friends', 'Location', 'Mail', 'Task'];
  private menuIcons: Array<Resource> = [$r('app.media.nav_call'), $r('app.media.nav_friends'), 
                                        $r('app.media.nav_location'), $r('app.media.nav_mail'), 
                                        $r('app.media.nav_task')];

  build() {
    SideBarContainer(SideBarPosition.Start) {
      // 侧边栏内容
      Column() {
        // 头部区域
        Column() {
          Image($r('app.media.nav_icon'))
            .width(70)
            .height(70)
            .borderRadius(35) // 圆形图片
            .margin({ top: 20, bottom: 10 })
          
          Text('User Name')
            .fontSize(16)
            .fontColor(Color.White)
            .margin({ bottom: 30 })
        }
        .width('100%')
        .backgroundColor('#007DFF')
        .padding(20)

        // 菜单列表
        List({ space: 10 }) {
          ForEach(this.menuItems, (item: string, index: number) => {
            ListItem() {
              Row() {
                Image(this.menuIcons[index])
                  .width(24)
                  .height(24)
                  .margin({ right: 15 })
                
                Text(item)
                  .fontSize(16)
                  .fontColor(this.selectedIndex === index ? '#007DFF' : Color.Black)
              }
              .width('100%')
              .padding(15)
            }
            .onClick(() => {
              this.selectedIndex = index;
              // 处理菜单点击事件
              this.handleMenuItemClick(index);
            })
          })
        }
        .width('100%')
        .layoutWeight(1)
      }
      .width(240) // 侧边栏宽度
      .height('100%')
      .backgroundColor(Color.White)

      // 主内容区域
      Column() {
        Text(`当前页面: ${this.menuItems[this.selectedIndex]}`)
          .fontSize(20)
          .margin(20)
        
        // 主页面内容...
      }
      .width('100%')
      .height('100%')
    }
    .sideBarWidth(240)
    .minSideBarWidth(240)
    .maxSideBarWidth(300)
    .autoHide(false) // 不自动隐藏
  }

  // 菜单点击处理函数
  private handleMenuItemClick(index: number): void {
    // 根据index执行不同操作
    switch(index) {
      case 0:
        // Call功能
        break;
      case 1:
        // Friends功能
        break;
      // ...其他case
    }
  }
}

2. 使用Navigation + Router实现页面导航

对于更复杂的应用,建议使用Navigation组件配合路由管理:

// 主页面
@Entry
@Component
struct MainPage {
  @State isMenuVisible: boolean = false;

  build() {
    Navigation() {
      // 首页内容
      HomePage()
    }
    .title('Main')
    .toolbar({
      // 添加菜单按钮
      leftItems: [
        {
          icon: $r('app.media.menu'),
          action: () => {
            this.isMenuVisible = !this.isMenuVisible;
          }
        }
      ]
    })
  }
}

// 侧边菜单组件
@Component
struct SideMenu {
  @Link isVisible: boolean;

  build() {
    // 侧边菜单实现...
  }
}

关键区别说明:

  1. 开发范式不同:HarmonyOS使用ArkTS声明式UI,而非Android的XML布局
  2. 组件体系不同:没有NavigationView,使用SideBarContainerNavigation组件
  3. 依赖管理:HarmonyOS使用HPM包管理器,不兼容Android的Gradle依赖
  4. 资源管理:使用$r('app.media.xxx')引用资源,而非@drawable/xxx
  5. 事件处理:使用.onClick()事件修饰符,而非setNavigationItemSelectedListener

建议:

  1. 参考HarmonyOS官方文档中的SideBarContainerNavigation组件用法
  2. 使用DevEco Studio的模板创建新项目,其中包含导航框架示例
  3. 学习ArkUI的声明式语法,这与传统的命令式Android开发有本质区别

你的Android实现思路是正确的,但需要转换为HarmonyOS Next的ArkUI实现方式。

回到顶部