当底部导航视图已经被创建时,重新创建片段。

4
在我的应用程序中,我正在使用BottomNavigationViewJetpack Navigation。我有四个片段:Home、Search、Notifications和Profile。当我在Home片段中,再次点击底部导航视图中的home项目时,它会重新创建该片段。我搜索过,但主要是针对那些没有使用jetpack navigation的答案。
(顺便说一下,我只希望在我已经在该片段上时不重新创建片段,如果我不在该片段上,重新创建就可以了)
以下是我的设置:
val navHostFragment = supportFragmentManager.findFragmentById(R.id.fragmentContainerView_mainActivity) as NavHostFragment
navController = navHostFragment.navController 
binding.bottomNavView.setupWithNavController(navController)

And this is the gif image that shows how bottom navigation view does behave

5个回答

0
如果当前项目ID与上一个ID相同,则返回false值。否则调用您选择的片段。
bottomNavigation.setOnItemSelectedListener { item ->
if (item.itemId == bottomNavigation.selectedItemId) {
    false
} else {
    when (item.itemId) {
        R.id.home -> {
            //replaceFragment
        }
        R.id.chats -> {
            //replaceFragment
        }
        R.id.setting -> {
            //replaceFragment
        }
    }
    true
 }

}

0

这是一个存在已久的错误,Google没有提供官方的解决方法。更多信息是因为只有一个堆栈在片段之间切换,您可以从SO的帖子中了解更多信息。

Android JetPack navigation with multiple stack

但是如果您使用Kotlin,您可以参考这个Github的repo,他们为这种情况提供了一种解决方法。


0

我阅读了Google的源代码。我发现它总是创建新的片段。

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

enter image description here

对我来说,我没有使用底部导航栏的菜单项。我为其添加了一个自定义视图。
(我拥有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)
            }
        })

0
我最终使用了下面的代码。(考虑到没有最佳解决方案,它对我来说是符合要求的) 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
            }

        }

0

这是使用 Jetpack Navigation 通过底部导航防止片段重新创建的正确方法。

 binding.bottomNavView.setOnNavigationItemReselectedListener {
        // Do nothing to ignore the reselection
    }

尽管setOnItemReselectedListener已经被弃用,但它仅解决了重新选择当前片段的问题。实际上,您应该使用setOnItemSelectedListener,并在那里进行适当的导航逻辑。但是,它仍然只解决了单击底部导航项以切换到当前可见片段的问题。 - M. Wojcik
@M.Wojcik 请查看 https://dev59.com/J1MH5IYBdhLWcg3wzzEe#58210550。 - Asad Mahmood

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接