【问题标题】:bottom navigation view fragment re-created when it is already created底部导航视图片段在已创建时重新创建
【发布时间】:2021-04-27 09:25:54
【问题描述】:

在我的应用程序中,我使用 Jetpack NavigationBottomNavigationView。我有 4 个片段:主页、搜索、通知、配置文件,当我在主页片段中时,我再次单击底部导航视图中的主页项,它重新创建片段。我搜索了,但主要是针对那些不使用喷气背包导航的人。

(顺便说一句,我只想在我已经在那个片段上时不重新创建片段,如果我不在那个片段中,可以重新创建)

以下是我的设置:

val navHostFragment = supportFragmentManager.findFragmentById(R.id.fragmentContainerView_mainActivity) as NavHostFragment
navController = navHostFragment.navController 
binding.bottomNavView.setupWithNavController(navController)

【问题讨论】:

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


    【解决方案1】:

    我阅读了谷歌的源代码。我看到了,它总是会创建新的片段。

    你有一个底部导航,就像我正在构建的应用程序一样。 :))

    对我来说,我没有将菜单项用于底部导航视图。我为它添加了一个自定义视图。

    (我有 MainActivity、MainViewModel 用于管理操作栏、底部导航视图。)

    然后在自定义视图中,当客户点击项目时,我会检查他们要打开的页面是否与当前页面相同。如果它们相同,我不会打开它。像这样:

    fun openHomePage() {
            if (pageID.value != R.id.nav_home) {
                pageID.postValue(R.id.nav_home)
            }
        }
    

    pageID 存储当前页面的id:

     var pageID = MutableLiveData<Int>()
            private set
    

    在 MainActivity 中:

    mainViewModel.pageID.observe(this, Observer {
                val currentPageId = findNavController(R.id.nav_host_fragment).currentDestination?.id
                if (it != 0 && it != currentPageId) {
                    drawerLayout.close()
                    navigatePageWithId(it)
                }
            })
    

    【讨论】:

      【解决方案2】:

      这是一个已经存在一段时间的错误,Google 尚未提供官方的处理方法。更多信息是,因为只有一个堆栈可以交换片段,您可以从 SO 的帖子中阅读更多内容

      Android JetPack navigation with multiple stack

      但是你使用的是 kotlin,你可以参考这个 Github 的 repo,他们为这种情况提供了解决方法

      【讨论】:

        【解决方案3】:

        我最终使用了下面的代码。(考虑到没有最好的解决方案,它对我有用) currentFragmentIndex 是在上述范围内声明的整数值,它显示了我们当前所在的片段。

        binding.bottomNavView.setOnNavigationItemSelectedListener {
                    when (it.itemId) {
                        R.id.homeFragment -> {
                            if (currentFragmentIndex == 0) {
                                false
                            } else {
                                currentFragmentIndex = 0
                                navController.navigate(R.id.homeFragment)
                                true
                            }
                        }
                        R.id.searchFragment -> {
                            if (currentFragmentIndex == 1) {
                                false
                            } else {
                                currentFragmentIndex = 1
                                navController.navigate(R.id.searchFragment)
                                true
                            }
                        }
                        R.id.notificationsFragment -> {
                            if (currentFragmentIndex == 2) {
                                false
                            } else {
                                currentFragmentIndex = 2
                                navController.navigate(R.id.notificationsFragment)
                                true
                            }
                        }
                        R.id.myProfileFragment -> {
                            if (currentFragmentIndex == 3) {
                                false
                            } else {
                                currentFragmentIndex = 3
                                navController.navigate(R.id.myProfileFragment)
                                true
                            }
                        }
                        else -> false
                    }
        
                }
        

        【讨论】:

          【解决方案4】:

          这是在通过 Jetpack Navigation

          使用底部导航时防止碎片重新生成的正确方法
           binding.bottomNavView.setOnNavigationItemReselectedListener {
                  // Do nothing to ignore the reselection
              }
          

          【讨论】:

          • 尽管这已经被弃用了 (setOnItemReselectedListener),但这仅解决了当前片段被选中时重新选择的问题。实际上,您应该使用setOnItemSelectedListener 并在那里进行适当的导航逻辑。但是,它仍然只解决了单击当前可见片段的底部导航项的问题。
          猜你喜欢
          • 1970-01-01
          • 2017-07-10
          • 2022-06-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多