当前位置: 首页 > 知识库问答 >
问题:

导航组件-导航抽屉问题

况庆
2023-03-14

实际上,我正在我的应用程序中使用新的架构组件,并且我已经设置了导航组件。我有一个导航抽屉,我想用它。我已经设置好了,但我面临一些问题:

1-抽屉不会自动关闭。菜单正常工作并导航到正确的位置,但导航后不会关闭。我必须添加一个目的地ChangedListener才能自己关闭它。

navController.addOnDestinationChangedListener { _, _, _ ->
    if (drawer_layout.isDrawerOpen(GravityCompat.START))
        drawer_layout.closeDrawer(GravityCompat.START)
}

在代码实验室里,抽屉自动关闭,我真的不明白为什么。

2-向上按钮打开抽屉。当我导航到非顶级片段时,菜单图标变为向上箭头,但当我单击它时,它会打开抽屉菜单,而不是返回到上一个目标。

3我想,对于我菜单中的一些项目,设置一个自定义点击。我菜单上的所有按钮都不是用来导航到应用程序的,我不知道我在哪里可以覆盖导航控制器的行为,告诉它当他无法导航时该做什么。

这是相关代码:

活动ain.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <include layout="@layout/layout_app_bar"/>

    <androidx.drawerlayout.widget.DrawerLayout
        android:id="@+id/drawer_layout"
        android:layout_marginTop="?attr/actionBarSize"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.coordinatorlayout.widget.CoordinatorLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

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

        </androidx.coordinatorlayout.widget.CoordinatorLayout>

        <include layout="@layout/layout_navigation_view"/>

    </androidx.drawerlayout.widget.DrawerLayout>

</FrameLayout>

Layout\u app\u栏。xml

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.appbar.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:theme="@style/AppTheme.AppBarOverlay"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/language_main_color"
        android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
        app:popupTheme="@style/AppTheme.PopupOverlay" />

</com.google.android.material.appbar.AppBarLayout>

drawer_menu.xml

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


    <group android:id="@+id/appAction" >
        <item
            android:id="@+id/bridgeFragment"
            android:icon="@drawable/ic_home"
            android:title="@string/home" />

        <item
            android:id="@+id/categoryFragment"
            android:icon="@drawable/ic_categories"
            android:title="@string/categories" />

        <item
            android:id="@+id/favoriteFragment"
            android:icon="@drawable/ic_favorite"
            android:title="@string/favorites" />

        <item
            android:id="@+id/unlimited"
            android:icon="@drawable/ic_unlimited"
            android:title="@string/dialog_ask_unlimited_title" />

        <!--<item
            android:id="@+id/settings"
            android:icon="@drawable/ic_settings"
            android:title="@string/settings" /> -->
    </group>


    <group android:id="@+id/globalAction">
        <item
            android:id="@+id/rate"
            android:icon="@drawable/ic_rate"
            android:title="@string/rate" />

        <item
            android:id="@+id/aboutFragment"
            android:icon="@drawable/ic_about_me"
            android:title="@string/about"/>
    </group>


</menu>

MainActivity.kt(setupMenus()和setupView()在onCreate中调用

override fun setupView(){

        val host: NavHostFragment = supportFragmentManager
                .findFragmentById(R.id.nav_host_fragment) as NavHostFragment? ?: return

        val navController = host.navController

        val drawerLayout : DrawerLayout? = findViewById(R.id.drawer_layout)
        appBarConfiguration = AppBarConfiguration(
                setOf(R.id.bridgeFragment, R.id.categoryFragment, R.id.favoriteFragment, R.id.aboutFragment),
                drawerLayout)

        setupActionBarWithNavController(navController, appBarConfiguration)
        setupNavigationMenu(navController)

        navController.addOnDestinationChangedListener { _, _, _ ->
            if (drawer_layout.isDrawerOpen(GravityCompat.START))
                drawer_layout.closeDrawer(GravityCompat.START)
        }
    }

    fun updateHasMenu(hasMenu: Boolean) { this.hasMenu = hasMenu }

    private fun setupNavigationMenu(navController: NavController) {
        val sideNavView = findViewById<NavigationView>(R.id.nav_view)
        sideNavView?.setupWithNavController(navController)
    }

    override fun onSupportNavigateUp(): Boolean {
        return findNavController(R.id.nav_host_fragment).navigateUp(appBarConfiguration)
    }

    override fun setupMenus(){
        setSupportActionBar(toolbar)
        supportActionBar?.let {
            it.setDisplayHomeAsUpEnabled(true)
            it.setHomeAsUpIndicator(R.drawable.ic_menu)
        }
    }

共有1个答案

查飞星
2023-03-14

这是你第一个、第二个和第三个问题的全部工作代码

class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {

private lateinit var navController: NavController

private lateinit var appBarConfiguration: AppBarConfiguration

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    setSupportActionBar(toolbar)
    navController = findNavController(R.id.nav_controller_fragment)
    appBarConfiguration = AppBarConfiguration(navController.graph,drawer_layout)
    setupActionBarWithNavController(navController,appBarConfiguration)

    drawer()

    setupNavigationMenu()
    nav_view.setNavigationItemSelectedListener(this)
}

private fun drawer() {
    drawer_layout.addDrawerListener(object :DrawerLayout.DrawerListener{
        override fun onDrawerStateChanged(newState: Int) {
        }

        override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
        }

        override fun onDrawerClosed(drawerView: View) {
        }

        override fun onDrawerOpened(drawerView: View) {
        }
    })
}


private fun setupNavigationMenu() {
    nav_view.let {
        NavigationUI.setupWithNavController(it, navController)
    }
}

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

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.main, menu)
    return true
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return when (item.itemId) {
        R.id.action_settings -> true
        else -> NavigationUI.onNavDestinationSelected(item,navController) || super.onOptionsItemSelected(item)

    }
}

override fun onNavigationItemSelected(item: MenuItem): Boolean {
    drawer_layout.closeDrawer(GravityCompat.START)
    return when (item.itemId) {
        R.id.nav_gallery -> true
        else ->
        NavigationUI.onNavDestinationSelected(
            item,navController) || super.onOptionsItemSelected(item)
    }
}

override fun onSupportNavigateUp(): Boolean {
    return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
}

这就是整个项目链接和apk。

 类似资料:
  • 有人能告诉我如何创建活动到这个主要活动,导航抽屉将看到在所有他们?我需要使用这个特定的MainActivity代码。我不需要使用碎片,只要3个简单的活动将添加到这个抽屉。 NavDrawer布局:

  • 我试图遵循谷歌最新的良好实践,用导航组件实现单个活动应用程序。 然而,在阅读了整个导航留档后,我仍然认为有很多情况下,他们没有解决。 例如,我应该如何实现以下情况: 应用程序在闪屏中启动。然后在加载后进入新闻片段。 注意:闪屏应该从后台弹出,因为它不应该再出现了。 然而,部分中的一些片段可以导航到一个新区域,该区域应该有一个后退按钮(而不是抽屉)。

  • 问题内容: 我有一个导航图,该导航图将此片段用作主活动XML中的主页。 我有一个带有菜单的Drawer布局,单击导航抽屉按钮时,我无法设法使导航正常工作(它可以从主要片段工作,但是当我单击Drawer按钮时,不能工作),如果我使用的是旧方法使用:对导航抽屉编程,我的navcontroller丢失了!!我得到类似的错误 navcontroller无法识别目标片段,因为即使不是这种情况,控制器也会看到

  • 我有一个导航图,它在主活动XML中使用这个片段作为主页。 我有一个带菜单的抽屉布局,当我点击抽屉菜单按钮时,我无法使导航工作(它从主片段工作,但当我点击抽屉按钮时就不工作),如果我使用旧的方式来编程抽屉菜单:

  • 我在将与和组合时遇到布局问题。 问题是,NavigationDrawer及其内容隐藏在工具栏后面。我已经做了很多研究,尝试了很多重组,但没有一个“解决方案”能解决我的问题。 在这个Webm小视频中可以找到一个演示:https://www.dropbox.com/s/i5zfc2x2ts2fws7/navigation_drawer_stackoverflow32523188.webm?dl=0 基

  • 有人知道如何实现一个滑动菜单像一些顶级应用程序今天吗? 其他堆栈溢出问题还没有关于如何做到这一点的答案,所以我正在尝试收集尽可能多的信息来帮助其他人。我在下面提到的所有应用程序都很好地实现了幻灯片菜单。 只有点击左上角的G+标识,才能从第一屏进入第二屏。注意,整个屏幕从它的位置移动,并且get被推到屏幕的右侧(包括操作栏)。要回到第一个屏幕,您可以将右侧滑回焦点,也可以再次单击G+图标。 您可以使