Android Fragments 底部导航视图片段在已创建时重新创建

2mbi3lxu  于 2023-03-23  发布在  Android
关注(0)|答案(5)|浏览(210)

在我的应用程序中,我使用Jetpack导航BottomNavigationView。我有4个片段:主页,搜索,通知,配置文件,当我在主页片段,我再次点击主页项目在底部导航视图,它重新创建片段。我搜索,但主要是答案是那些谁不使用喷气背包导航。
(by顺便说一句,我只希望当我已经在那个片段上时片段不被重新创建,如果我不在那个片段中,可以重新创建)
下面是我的设置:

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

z9smfwbn

z9smfwbn1#

我读了谷歌的源代码。我看到,它总是创建新的片段。
你有一个底部导航像我正在构建的应用程序。:))

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

主要活动:

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

wd2eg0qa2#

这是一个已经存在了一段时间的bug,Google还没有提供官方的方法来处理它。更多的信息是,因为只有一个堆栈交换片段,你可以从SO的帖子中阅读更多
Android JetPack navigation with multiple stack
但是你使用的是Kotlin,你可以参考这个Github的repo,他们为这种情况提供了一个解决方案

xkftehaa

xkftehaa3#

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

        }
rm5edbpk

rm5edbpk4#

这是正确的方法,以防止碎片从娱乐,而使用底部导航通过喷气背包导航

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

3wabscal5#

如果当前项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
 }

}

相关问题