如何使用导航控制器设置导航抽屉并处理单个菜单项

时间:2018-08-08 09:52:40

标签: android android-navigation-drawer android-architecture-components android-navigation

我希望大多数菜单项都由Navigation Component的控制器处理,但我也想像这样单独处理一个“注销”菜单项:

g = sns.jointplot("s_zscore","p_zscore",s=2, data=scatter_all, kind="kde",levels=density_levels+[0.09])

为什么这不起作用,以及如何解决此问题?

2 个答案:

答案 0 :(得分:3)

我不确定目前是否有适当的方法来执行此操作,但是您始终只能不使用setupWithNavController方法。

我也遇到了这个问题,并且作为测试,将对setNavigationItemSelectedListener的呼叫转移到setupWithNavController ,并且我退出的导航代码是正在运行,但其余导航未运行。我的意思是说,在随后对setNavigationItemSelectedListener的调用中,navigationListener被覆盖,而setupWithNavController在内部的setNavigationItemSelectedListener调用中被覆盖。

我试图在google来源中对此进行验证,但无法轻松找到该存储库。

我通过不调用setupWithNavController来解决此问题,而是执行了以下操作:

    navigationDrawer?.setNavigationItemSelectedListener { menuItem ->
        if (menuItem.itemId == R.id.action_sign_out) {
            // sign out logic
            return@setNavigationItemSelectedListener true
        }

        val result = menuItem.onNavDestinationSelected(navigationController)
        drawerLayout?.closeDrawers()
        result
    }

答案 1 :(得分:0)

类似于贾斯汀的答案,我从NavigationUI复制了侦听器设置代码,如下所示:

fun NavigationView.setupWithNavController(navController: NavController, onMenuItemSelected: (MenuItem) -> Boolean) {
    NavigationUI.setupWithNavController(this, navController) // because this does more than set the nav view listener
    setNavigationItemSelectedListener { item ->
        if (onMenuItemSelected(item)) {
            return@setNavigationItemSelectedListener true
        }
        NavigationUI.onNavDestinationSelected(item, navController).also {
            val parent = parent
            if (parent is DrawerLayout) {
                parent.closeDrawer(this)
            } else {
                findBottomSheetBehavior()?.state = BottomSheetBehavior.STATE_HIDDEN
            }
        }
    }
}

private fun View.findBottomSheetBehavior(): BottomSheetBehavior<*>? {
    val params = layoutParams
    if (params !is CoordinatorLayout.LayoutParams) {
        return (parent as? View)?.findBottomSheetBehavior()
    }
    return params.behavior as? BottomSheetBehavior<*>
}

然后在Activity.onCreate()中:

navigation_view.setupWithNavController(navController) { item ->
    when (item.itemId) {
        R.id.mySpecialFragment ->
            // do something special like: navController.popBackStack(id, true)
    }
    false // usually still want to perform default steps
}

更防弹的解决方案可能涉及子类NavigationView并覆盖setNavigationItemSelectedListener(),以便您可以将NavigationUI设置的实际监听器包装为包含对您自己的监听器的调用的包装通过某个公共设置器传递。