Backpress 错误图标上的底部导航视图

Bottom Navigation View on Backpress wrong icon

我的 MainActivity 中有 3 个带有 NavigationGraph 和 BottomNavigationView 的片段。这些片段是 HomeFragment、DashboardFragment 和 NotificationFragment。 startDestination 是 DashboardFragment,所以当我启动应用程序时,它会显示 DashboardFragment。

当我按下后退按钮时出现问题。片段显示 DashboardFragment,但 BottomNavigationView 显示最右侧的菜单,即 NotificationFragment。我希望展示 DashboardFragment 和 DashboardMenu。如何解决?

这是我的代码:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val view = ActivityMainBinding.inflate(layoutInflater)
    setContentView(view.root)
    
    val navController = findNavController(R.id.nav_host_fragment)
    view.navView.setOnNavigationItemSelectedListener {
        if (navController.currentDestination!!.id != it.itemId) {
            val builder = NavOptions.Builder()
                .setLaunchSingleTop(true)
            if (it.order and Menu.CATEGORY_SECONDARY == 0) {
                builder.setPopUpTo(findStartDestination(navController.graph).id, false)
            }
            val options = builder.build()
            try {
                navController.navigate(it.itemId, null, options)
            } catch (e: IllegalArgumentException) {
                e.printStackTrace()
            }
        }
        true
    }
    navController.addOnDestinationChangedListener { _, destination, _ ->
        val menu = view.navView.menu
        for (i in 0 until menu.size()) {
            val item = menu[i]
            val menuId = item.itemId
            val destinationId = destination.id
            val checked = menuId == destinationId
            item.isChecked = checked
        }
    }
}

尝试将此添加到 activity:

override fun onBackPressed() {
    super.onBackPressed()
    navView.setSelectedItemId(R.id.menu_dashbord)
    //jump to dashbord fragment
}

我建议更改您的实现,以便它使用 androidx.navigation.ui 包中的 setupWithNavController 扩展函数。

在activity的xml

(...)
     <com.google.android.material.bottomnavigation.BottomNavigationView
            android:id="@+id/bottom_navigation"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:menu="@menu/bottom_navigation_menu" />
(...)

在activity

a) 声明 bottomNavigation

private val bottomNavigation: BottomNavigationView by lazy { findViewById(R.id.bottom_navigation) }

b) 创建设置导航函数并在 onCreate 方法中调用它

private fun setupNavigation() {
        val navHostFragment =
            supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment

        val navController = navHostFragment.navController
        navController.addOnDestinationChangedListener(this)
        bottomNavigation.setupWithNavController(navController)
    }

这样后退按钮将自动正确处理

PS。如果您不希望在重新选择菜单项时重新创建片段,请在 bottomNavigationView 上设置 NavigationItemReselectedListener。

像 activity 的字段一样初始化 navController:

 val navController by lazy { findNavController(R.id.nav_host_fragment) }

在 activity onCreate 中初始化底部导航:

bottom_nav?.setupWithNavController(navController)

在你的 activity 上重写这个乐趣(为了正确的后退按钮):

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

在菜单文件中添加相同的名称,在导航图中添加片段 ID。必须工作

另外,如果你想在你的片段中使用 navController 来导航某处:

protected lateinit var rootActivity: MainActivity
<...>
override fun onAttach(context: Context) {
    super.onAttach(context)
    rootActivity = activity as MainActivity
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
   btn_action.setOnClickListener {    
       rootActivity.navController.navigate(R.id.action_id)
   }
}

action_id 是你在导航图中写的动作的id

此外,从 onCreate()

中删除所有监听器