首页 > 解决方案 > 带有 NavigationDrawer 的导航组件

问题描述

我正在尝试在我的项目中使用导航组件实现 NavigationDrawer。我有一个 MainActivity 作为入口点和多个片段目的地。我已将抽屉菜单项链接到 nav_graph.xml 中的目的地,一切正常。

我的 NavigationDrawer 中有一个“注销”菜单项选项,单击它我正在启动 LoginActivity。我的问题是

  1. 我将 LoginActivity 添加到我的 nav_graph 并将其链接到抽屉中的注销菜单项,这是正确的方法吗?
  2. 启动 LoginActivity 后,当用户按下系统后退按钮时,我希望应用程序转到启动器屏幕而不是堆栈中的先前目的地。这可以通过导航组件实现吗?

这是我的 nav_graph.xml

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_graph"
    app:startDestination="@id/dashboardFragment">

    <fragment
        android:id="@+id/dashboardFragment"
        android:name="com.example.fragment.DashboardFragment"
        android:label="DashboardFragment"
        tools:layout="@layout/fragment_dashboard" />
    <fragment
        android:id="@+id/profileFragment"
        android:name="com.example.fragment.ProfileFragment"
        android:label="ProfileFragment"
        tools:layout="@layout/fragment_profile" />
    <fragment
        android:id="@+id/settingsFragment"
        android:name="com.example.fragment.SettingsFragment"
        android:label="SettingsFragment"
        tools:layout="@layout/fragment_sale_edit" />
    <activity
        android:id="@+id/loginActivity"
        android:name="com.example.activity.LogoutActivity"
        android:label="LogoutActivity"></activity>
</navigation>

这是我的drawer_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:showIn="navigationView">

    <group android:checkableBehavior="single">
        <item
            android:id="@+id/dashboardFragment"
            android:icon="@drawable/ic_menu_camera"
            android:title="Dashboard" />
        <item
            android:id="@+id/profileFragment"
            android:icon="@drawable/ic_menu_gallery"
            android:title="Profile" />
        <item
            android:id="@+id/settingsFragment"
            android:icon="@drawable/ic_menu_slideshow"
            android:title="Sale Edits" />
        <item
            android:id="@+id/loginActivity"
            android:icon="@drawable/ic_menu_manage"
            android:title="Logout" />
    </group>

</menu>



<fragment
        android:id="@+id/navHostFragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph"/>

标签: androidnavigation-drawerandroid-navigationandroid-architecture-navigation

解决方案


我认为更好的解决方案是使用登录作为片段而不是活动,并且工具栏处理应该从您的活动中完成。您的活动应如下所示:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    setSupportActionBar(toolbar)
    supportActionBar?.setDisplayHomeAsUpEnabled(true)
    supportActionBar?.setDisplayShowHomeEnabled(true)
    setupActionBarWithNavController(this, findNavController(nav_host_fragment),drawer_layout)
    setupWithNavController(nav_view, findNavController(nav_host_fragment))

    NavHostFragment.findNavController( nav_host_fragment ).addOnNavigatedListener { controller, destination ->
        when(destination.id) {
            R.id.loginFragment -> {
                drawer_layout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
                toolbar.visibility= View.GONE
            }
            R.id.dashboardFragment -> {
                drawer_layout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
                toolbar.visibility= View.VISIBLE
            }
            else -> {
                drawer_layout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
                toolbar.visibility= View.VISIBLE
            }
        }
    }
}

override fun onBackPressed() {
    if (drawer_layout.isDrawerOpen(GravityCompat.START)) {
        drawer_layout.closeDrawer(GravityCompat.START)
    } else {
        super.onBackPressed()
    }
}

override fun onOptionsItemSelected(item: MenuItem?): Boolean {
    when(item?.itemId) {
        android.R.id.home -> {
            if(NavHostFragment.findNavController( nav_host_fragment ).currentDestination.id==R.id.dashboardFragment) {
                drawer_layout.openDrawer(GravityCompat.START)
                return true
            }
        }
    }
    return super.onOptionsItemSelected(item)
}

override fun onSupportNavigateUp()= findNavController(nav_host_fragment).navigateUp()

推荐阅读