You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Navigation Drawer汉堡图标添加切换动画(无需自定义ActionBar)

问题描述

复习一年前学习的纳米学位视频巩固知识时,遇到Navigation组件项目的问题:使用MVVM模式+Navigation Drawer搭配汉堡图标,点击汉堡仅能打开抽屉,再次点击无法关闭。此前用Flutter时,系统会自动在汉堡图标和返回键间切换并附带过渡动画,希望在Android项目中实现该效果,且不自定义ActionBar。


项目相关代码

activity_main.xml

<androidx.drawerlayout.widget.DrawerLayout
    android:id="@+id/drawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <fragment
            android:id="@+id/myNavHostFragment"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:defaultNavHost="true"
            app:navGraph="@navigation/navigation" />
    </LinearLayout>

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/navView"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/nav_header"
        app:menu="@menu/navdrawer_menu" />
</androidx.drawerlayout.widget.DrawerLayout>

MainActivity.kt(原代码)

class MainActivity : AppCompatActivity() {
private lateinit var drawerLayout: DrawerLayout
private lateinit var appBarConfiguration : AppBarConfiguration
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
    drawerLayout = binding.drawerLayout
    val navController = this.findNavController(R.id.myNavHostFragment)
    NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout)
    appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout)
    // prevent nav gesture if not on start destination
    navController.addOnDestinationChangedListener { nc: NavController, nd: NavDestination, bundle: Bundle? ->
        if (nd.id == nc.graph.startDestination) {
            drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
        } else {
            drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
        }
    }
    NavigationUI.setupWithNavController(binding.navView, navController)
}

override fun onSupportNavigateUp(): Boolean {
    val navController = this.findNavController(R.id.myNavHostFragment)
    return NavigationUI.navigateUp(navController, appBarConfiguration)
    }
}

解决方案

无需自定义ActionBar,仅需调整AppBarConfiguration的初始化顺序,依托Navigation组件官方API即可实现需求:

修改后的MainActivity.kt代码

class MainActivity : AppCompatActivity() {
    private lateinit var drawerLayout: DrawerLayout
    private lateinit var appBarConfiguration: AppBarConfiguration

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
        drawerLayout = binding.drawerLayout
        val navController = this.findNavController(R.id.myNavHostFragment)

        // 先初始化AppBarConfiguration,再绑定ActionBar
        appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout)
        NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration)

        // 页面切换时控制抽屉手势
        navController.addOnDestinationChangedListener { nc: NavController, nd: NavDestination, _: Bundle? ->
            if (nd.id == nc.graph.startDestination) {
                drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
            } else {
                drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
            }
        }
        NavigationUI.setupWithNavController(binding.navView, navController)
    }

    override fun onSupportNavigateUp(): Boolean {
        val navController = this.findNavController(R.id.myNavHostFragment)
        return NavigationUI.navigateUp(navController, appBarConfiguration)
    }
}

原理说明

  1. 图标自动切换与动画:AppBarConfiguration会根据当前页面是否为导航图起始目的地,自动在汉堡图标和返回键间切换,且自带系统过渡动画。
  2. 汉堡图标开关抽屉:传入正确配置的AppBarConfiguration后,setupActionBarWithNavController会自动处理汉堡图标的点击逻辑——抽屉打开状态下再次点击即可关闭。
  3. 复用系统ActionBar:所有逻辑基于Navigation组件官方实现,无需自定义ActionBar,完全复用系统原生控件功能。

内容的提问来源于stack exchange,提问作者Omar A. Khaled

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 00:35:31