Android导航架构组件-导航抽屉图标

Android导航架构组件-导航抽屉图标,android,navigation-drawer,android-jetpack,android-architecture-navigation,android-components,Android,Navigation Drawer,Android Jetpack,Android Architecture Navigation,Android Components,我目前正在使用Android架构组件的导航,但我的导航抽屉遇到了问题。当我到达目的地时,它会显示汉堡包菜单,但其他片段会显示向上箭头。我想我的导航图设置不正确 在这里你可以看到我的导航抽屉,显示了两个项目,主页和设置。在这些片段中,您应该看到汉堡图标 但是,当导航到设置片段时,它会显示向上箭头 navigation.graph.xml 主要活动 然后在MainActivity中,我只是这样设置它。我用NavController调用了setupActionBar,但我还必须自己实际设置导航抽屉

我目前正在使用Android架构组件的
导航
,但我的
导航抽屉遇到了问题。当我到达目的地时,它会显示汉堡包菜单,但其他
片段会显示向上箭头。我想我的
导航图设置不正确

在这里你可以看到我的导航抽屉,显示了两个项目,主页和设置。在这些片段中,您应该看到汉堡图标

但是,当导航到设置片段时,它会显示向上箭头

navigation.graph.xml 主要活动 然后在
MainActivity
中,我只是这样设置它。我用NavController调用了
setupActionBar
,但我还必须自己实际设置导航抽屉,并处理所选导航项的
onNavigationItem

private fun setupNavigation() {
    navController = findNavController(R.id.mainNavigationFragment)
    setupActionBarWithNavController(this, navController, drawer_layout)

    val toggle = ActionBarDrawerToggle(
                this, drawer_layout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
        drawer_layout.addDrawerListener(toggle)
        toggle.syncState()

    nav_view.setNavigationItemSelectedListener(this)
}

override fun onNavigationItemSelected(item: MenuItem): Boolean {
    val current = navController.currentDestination.id
    if (item.itemId != current) {
        navController.navigate(item.itemId)
    }

    drawer_layout.closeDrawers()
    return true
}
格雷德尔先生

// Navigation
implementation 'android.arch.navigation:navigation-fragment-ktx:1.0.0-alpha04'
implementation 'android.arch.navigation:navigation-ui-ktx:1.0.0-alpha04'
谢谢。

恐怕这是一个错误

当您在非根目标上时,操作栏还将显示“向上”按钮,当您在根目标上时,操作栏将显示抽屉图标,并在它们之间自动设置动画


如果需要,您可以尝试自己使用和处理工具栏。

BottomNavigationView
关联的选项卡片段上出现的后退箭头是一种预期行为。然而,即使在著名的应用程序(Instagram、Youtube等有底部标签的应用程序)中,也没有看到它被“按原样”使用。例如,若你们在Youtube应用程序中导航到不同的底部选项卡,然后单击设备返回选项,你们会注意到它会转到上一个选项卡片段,而不是退出应用程序。因此,bottomnavigationview选项卡片段在这里不是根目的地

希望在前进过程中注意到可能遇到的其他重要问题:

  • 它不允许将片段与
    BottomNavigationView

  • 如果有多个活动,“向上”按钮不会向上导航到上一个活动

但是,有几个钩子可用于定制行为:

  • on反按
    -如果抽屉打开,则关闭抽屉布局

    override fun onBackPressed() {
        if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
          drawerLayout.closeDrawer(GravityCompat.START)
        } else {
          super.onBackPressed()
        }
     }
    
  • 添加
    navController.addOnNavigatedListener(..)
    并在listener内自定义HomeAsUpIndicator图标

  • 覆盖OnOptions ItemSelected以使用id
    android.R.id.home
    操作自定义菜单

  • 设置自定义片段导航器以自定义片段的处理方式(替换或显示/隐藏)


  • 请记住,导航拱门组件仍在alpha中,因此请明智地使用它。

    我认为您的菜单项应如下所示:

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
    
        <item
                android:id="@id/nav_home"
                android:icon="@drawable/ic_home_white_24dp"
                android:title="@string/home" />
    
            <item
                android:id="@id/nav_settings"
                android:icon="@drawable/ic_settings_white_24dp"
                android:title="@string/settings" />
    
    </menu>
    
    
    
    希望这有帮助

    快乐编码

    如果需要,可以使用和使用下面的代码来设置标题

    @Override
    public void onNavigated(@NonNull NavController controller, @NonNull NavDestination destination) {
        mActivityBinding.toolbar.setTitle(destination.getLabel());
    }
    

    记住在导航图中设置标签。

    我完全同意这里的观点,但它是库的一部分

    setupActionBarWithNavController

    设置AppCompatActivity.getSupportActionBar()返回的ActionBar,以便与NavController一起使用

    通过调用此方法,当目标更改时(假设存在有效标签),操作栏中的标题将自动更新

    导航图的起始目的地被视为唯一的顶级目的地。如果给定的抽屉布局非空,则在导航图的开始目标上,ActionBar将显示抽屉图标。在所有其他目的地,ActionBar将显示向上按钮。调用navigateUp(导航控制器,抽屉布局)处理向上按钮。

    这对我来说是坏的,不是期望的结果,所以我所做的仍然是使用导航视图使用它

        navController = Navigation.findNavController(this, R.id.nav_host);
        NavigationUI.setupWithNavController(navigationView,navController);
    
    然后有一个监听器来更新标题和其他我想更改的内容

       navController.addOnNavigatedListener((controller, destination) -> {
            setToolbarColour(R.color.primary);
            switch (destination.getId()){
                case R.id.dashBoard :
                    setToolbarColour(android.R.color.transparent);
                    break;
                case R.id.requests :
                    toolbar.setTitle(getString(R.string.request));
                    break;
    
            }
        });
    
        val navController = findNavController(R.id.nav_host_fragment)
        val config = AppBarConfiguration(
            setOf(
                R.id.fistTopFragment,
                R.id.secondTopFragment,
                ...
            ),
            dr.drawerLayout
        )
        tb.setupWithNavController(navController, config)
    
    override fun onBackPressed() {
        val navController = findNavController(R.id.nav_host_fragment)
        if (navController.currentDestination == null
            || navController.currentDestination!!.id in setOf(
                R.id.fistTopFragment,
                R.id.secondTopFragment,
                ...
            )
        ) {
            super.onBackPressed()
        } else {
            navController.navigateUp()
        }
    }
    
    override fun onSupportNavigateUp(): Boolean {
        return NavigationUI.navigateUp(navController, appBarConfiguration)
    }
    
    然后,我为这些片段中的每一个创建了一个新的导航图,虽然不是很好,但我在较新的alphas(我有1.0.0-alpha07)中得到了预期的结果,他们在调用
    AppBarConfiguration
    构造函数时增加了定义
    TopLevelDestinationId
    的可能性

    所以我把导航控制器设置成这样

       navController.addOnNavigatedListener((controller, destination) -> {
            setToolbarColour(R.color.primary);
            switch (destination.getId()){
                case R.id.dashBoard :
                    setToolbarColour(android.R.color.transparent);
                    break;
                case R.id.requests :
                    toolbar.setTitle(getString(R.string.request));
                    break;
    
            }
        });
    
        val navController = findNavController(R.id.nav_host_fragment)
        val config = AppBarConfiguration(
            setOf(
                R.id.fistTopFragment,
                R.id.secondTopFragment,
                ...
            ),
            dr.drawerLayout
        )
        tb.setupWithNavController(navController, config)
    
    override fun onBackPressed() {
        val navController = findNavController(R.id.nav_host_fragment)
        if (navController.currentDestination == null
            || navController.currentDestination!!.id in setOf(
                R.id.fistTopFragment,
                R.id.secondTopFragment,
                ...
            )
        ) {
            super.onBackPressed()
        } else {
            navController.navigateUp()
        }
    }
    
    override fun onSupportNavigateUp(): Boolean {
        return NavigationUI.navigateUp(navController, appBarConfiguration)
    }
    
    其中
    dr
    是MaterialDrawer,当然是
    tb
    工具栏

    然后它的行为更像Gmail,至少对于
    ActionBarDrawerToggle
    ,后堆栈仍然保留。因为我必须自己处理MaterialDrawer中的项目选择,所以我将使用全局导航操作和包含的popTo将后堆栈操作减少到导航图的根片段,并暂时使用类似“欢迎屏幕”的东西

    另一种解决方法是自定义处理
    onBackPressed
    。 您必须首先从活动布局中的主机片段中删除
    app:defaultNavHost=“true”
    。像这样的

       navController.addOnNavigatedListener((controller, destination) -> {
            setToolbarColour(R.color.primary);
            switch (destination.getId()){
                case R.id.dashBoard :
                    setToolbarColour(android.R.color.transparent);
                    break;
                case R.id.requests :
                    toolbar.setTitle(getString(R.string.request));
                    break;
    
            }
        });
    
        val navController = findNavController(R.id.nav_host_fragment)
        val config = AppBarConfiguration(
            setOf(
                R.id.fistTopFragment,
                R.id.secondTopFragment,
                ...
            ),
            dr.drawerLayout
        )
        tb.setupWithNavController(navController, config)
    
    override fun onBackPressed() {
        val navController = findNavController(R.id.nav_host_fragment)
        if (navController.currentDestination == null
            || navController.currentDestination!!.id in setOf(
                R.id.fistTopFragment,
                R.id.secondTopFragment,
                ...
            )
        ) {
            super.onBackPressed()
        } else {
            navController.navigateUp()
        }
    }
    
    override fun onSupportNavigateUp(): Boolean {
        return NavigationUI.navigateUp(navController, appBarConfiguration)
    }
    

    很抱歉,我还在学习Kotlin,所以可能有更好的方法来实现这一点。

    我为这个问题举了一个简单的例子。解决方案几乎和全能者的答案相同

    首先创建一组顶级目的地

    val topLevelDestinations = setOf(R.id.garden_fragment,
            R.id.plant_list_fragment)
    appBarConfiguration = AppBarConfiguration.Builder(topLevelDestinations)
            .setDrawerLayout(drawerLayout)
            .build()
    
    然后像这样重写onSupportNavigateUp函数

       navController.addOnNavigatedListener((controller, destination) -> {
            setToolbarColour(R.color.primary);
            switch (destination.getId()){
                case R.id.dashBoard :
                    setToolbarColour(android.R.color.transparent);
                    break;
                case R.id.requests :
                    toolbar.setTitle(getString(R.string.request));
                    break;
    
            }
        });
    
        val navController = findNavController(R.id.nav_host_fragment)
        val config = AppBarConfiguration(
            setOf(
                R.id.fistTopFragment,
                R.id.secondTopFragment,
                ...
            ),
            dr.drawerLayout
        )
        tb.setupWithNavController(navController, config)
    
    override fun onBackPressed() {
        val navController = findNavController(R.id.nav_host_fragment)
        if (navController.currentDestination == null
            || navController.currentDestination!!.id in setOf(
                R.id.fistTopFragment,
                R.id.secondTopFragment,
                ...
            )
        ) {
            super.onBackPressed()
        } else {
            navController.navigateUp()
        }
    }
    
    override fun onSupportNavigateUp(): Boolean {
        return NavigationUI.navigateUp(navController, appBarConfiguration)
    }
    

    我试着按照指导原则,在“根目的地”上显示一个汉堡包图标,在“非根目的地”上显示向上按钮,但在“主目的地”以外的其他“根目的地”上显示向上按钮。根据创建者的说法,这是有意为之的行为,所以你只是在与库作斗争。至于我,我其实喜欢有一个启动屏幕,即使是抽屉。当我转到“设置”时,很有可能,当我按“上一步”时,我想继续使用该应用程序,而不是最终进入launcher。事实上,其中一条评论说这实际上是一个bug。它正在被追踪。您所指的问题涉及嵌套图。你的情况似乎不是这样。但是无论如何,试一下新版本。我意识到我实际上正在运行
    alpha04