фрагмент нижнего навигационного представления воссоздается, когда он уже создан

В своем приложении я использую Jetpack Navigation с BottomNavigationView. У меня есть 4 фрагмента: «Домой», «Поиск», «Уведомления», «Профиль», и когда я нахожусь в домашнем фрагменте, я снова нажимаю домашний элемент в нижнем навигационном представлении, он повторно создает фрагмент. Я искал, но в основном ответы были для тех, кто не пользовался навигацией на джетпаке.

(кстати, я хочу, чтобы фрагмент не воссоздавался только тогда, когда я уже нахожусь в этом фрагменте, если я не в этом фрагменте, можно воссоздать его)

Ниже моя установка:

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

А это gif-изображение, показывающее, как ведет себя нижняя панель навигации




Ответы (4)


Я прочитал исходный код Google. Я видел это, он всегда создает новый фрагмент.

У вас есть нижняя навигация, как в приложении, которое я создаю. :))

введите здесь описание изображения

Что касается меня, я не использовал пункт меню для нижней навигации. Я добавил для него настраиваемый вид.

(У меня есть MainActivity, MainViewModel для управления панелью действий, нижней панелью навигации.)

А затем в пользовательском представлении, когда клиент нажимает на элемент, я проверяю, совпадает ли страница, которую он хочет открыть, с текущей страницей или нет. Если они одинаковые, я не буду его открывать. Как это:

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

pageID хранит идентификатор текущей страницы:

 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)
            }
        })
person NhatVM    schedule 27.04.2021

Это ошибка, которая существует уже некоторое время, и Google не предоставил официального способа борьбы с ней. Дополнительная информация заключается в том, что, поскольку существует только один стек, который меняет местами фрагмент, вы можете прочитать больше из сообщения SO.

Навигация Android JetPack с несколькими стеками

Но вы используете kotlin, вы можете обратиться к репозиторию Github где они предложили обходной путь для этой ситуации

person Phúc Nguyễn    schedule 27.04.2021

В итоге я использовал код ниже. (Учитывая, что это не лучшее решение, оно работает для меня так, как я хочу) 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
            }

        }
person nesibeyyubov    schedule 30.04.2021

Это правильный способ предотвратить воссоздание фрагментов при использовании нижней навигации с помощью Jetpack Navigation.

 binding.bottomNavView.setOnNavigationItemReselectedListener {
        // Do nothing to ignore the reselection
    }
person asad mahmood    schedule 30.04.2021