【问题标题】:How to handle BottomNavBar menu listener with Navigation architecture component如何使用导航架构组件处理 BottomNavBar 菜单侦听器
【发布时间】:2020-11-27 09:29:35
【问题描述】:

在我最近的项目中,我使用带有底部导航栏的导航组件。 BottomNavBar 有 4 个菜单。对于前 3 个菜单,我在 NavGraph 文件中定义了片段,但对于最后一个菜单项,我必须打开 Drawer。

现在,前 3 个菜单的单击侦听器工作正常,因为所有三个片段都在打开。但我无法打开抽屉。

这是代码

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

    binding.bottomNav.setupWithNavController(host.navController)
}

我也尝试过像这样添加 NavigationItemSelectedListener,但应用程序在处理 backStack 时丢失了。就像按下后退按钮一样,之前打开的所有片段都会一次又一次地出现。

binding.bottomNav.setOnNavigationItemSelectedListener {
        when(it.itemId){
            R.id.homeFragment->{
                navController.navigate(R.id.homeFragment)
                true
            }
            R.id.latestFragment->{
                navController.navigate(R.id.latestFragment)
                true
            }
            R.id.cartFragment->{
                navController.navigate(R.id.cartFragment)
                true
            }
            else->{
                binding.drawerLayout.openDrawer(GravityCompat.START)
                false //Don't want to check more menu item
            }
        }
    }

请任何人提出任何想法。

【问题讨论】:

    标签: android kotlin android-fragments android-jetpack-navigation android-bottomnav


    【解决方案1】:

    终于找到了这个解决方案,但是还在等待更优化的解决方案。

    private fun setupBottomNavMenu(navController: NavController) {
    
        binding.bottomNav.setOnNavigationItemSelectedListener {
            when(it.itemId){
                R.id.homeFragment->{
                    navController.popBackStack(R.id.homeFragment, true)
                    navController.navigate(R.id.homeFragment)
                    true
                }
                R.id.latestFragment->{
                    navController.popBackStack(R.id.homeFragment, false)
                    navController.navigate(R.id.latestFragment)
                    true
                }
                R.id.cartFragment->{
                    navController.popBackStack(R.id.homeFragment, false)
                    navController.navigate(R.id.cartFragment)
                    true
                }
                else->{
                    binding.drawerLayout.openDrawer(GravityCompat.START)
                    false //Don't want to check more menu item
                }
            }
        }
    }
    

    还需要明确检查菜单项。

    private fun observeNavElements() {
        navController.addOnDestinationChangedListener { _, destination, _ ->
            when (destination.id) {
                R.id.homeFragment -> binding.bottomNav.menu.findItem(R.id.homeFragment).isChecked = true
                R.id.latestFragment -> binding.bottomNav.menu.findItem(R.id.latestFragment).isChecked = true
                else -> binding.bottomNav.menu.findItem(R.id.cartFragment).isChecked = true
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      您更新的代码现在是否打开导航抽屉?我可以看到您没有为抽屉式导航指定itemId,而是在else 块中处理它。

      binding.bottomNav.setOnNavigationItemSelectedListener {
              when(it.itemId){
                  R.id.homeFragment->{
                      navController.popBackStack(R.id.homeFragment, true)
                      navController.navigate(R.id.homeFragment)
                      true
                  }
                  R.id.latestFragment->{
                      navController.popBackStack(R.id.homeFragment, false)
                      navController.navigate(R.id.latestFragment)
                      true
                  }
                  R.id.cartFragment->{
                      navController.popBackStack(R.id.homeFragment, false)
                      navController.navigate(R.id.cartFragment)
                      true
                  }
                  R.id.navigationDrawer->{ // << HERE
                      binding.drawerLayout.openDrawer(GravityCompat.START)
                      false //Don't want to check more menu item
                  }
              }
          }
      

      【讨论】:

      • 感谢提及。抽屉正在使用 else 块打开,但是我将添加特定的项目 id 而不是 else。因为它将来可能会导致错误:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-03
      • 1970-01-01
      相关资源
      最近更新 更多