График компонентов Android Navigation перестает работать должным образом, когда я использую navController в наблюдателе LiveData

Я использую компонент навигации Android в своем демонстрационном приложении. У меня довольно простой случай. Одно действие, два фрагмента, A и B. Я настроил элементы управления навигацией, как в примере приложения от Google. И когда я пытаюсь открыть фрагмент B из A с помощью простого onClickListener, например:

val button.setOnClickListener {
       val action = AFragmentDirections.openFragmentB()
       findNavController().navigate(action)
    }

Все нормально работает. Фрагмент B открывается, и при нажатии на кнопку «Назад» он всплывает. Но когда я пытаюсь использовать его из наблюдателя LiveData, например:

viewModel.openFragmentB.observe(viewLifecycleOwner, Observer {
        val action = AFragmentDirections.openFragmentB()
        findNavController().navigate(action)
    })

Фрагмент B открывается, но при нажатии на кнопку «Назад» приложение вылетает с ошибкой назначения навигации com.myapp: id / open_fragmetn_b неизвестен этому NavController.

Почему это происходит и как использовать компонент навигации с LiveData?


person Alexandr Sushkov    schedule 01.12.2018    source источник


Ответы (1)


Этот сбой происходит из-за того, что, когда вы нажимаете кнопку возврата, ваш наблюдатель openFragmentB модели просмотра снова получает уведомление и пытается перейти к фрагменту B с помощью действия openFragmentB, но в этот момент текущим пунктом назначения NavController по-прежнему является фрагмент B, а фрагмент B не есть действие openFragmentB.

Для этого есть несколько решений, простое - добавить внутри вашего наблюдателя проверку, не является ли значение нулевым, и в конце установить значение openFragmentB на null:

if(it!=null) {
    val action = AFragmentDirections.openFragmentB()
    findNavController().navigate(action)
    viewModel.openFragmentB.value=null
}

Но для лучшего подхода вы можете прочитать о SingleLIveEvent: https://medium.com/androiddevelopers/livedata-with-snackbar-navigation-and-other-events-the-singleliveevent-case-ac2622673150

person Alex    schedule 02.12.2018
comment
Я уже использую LiveEvent, но по какой-то причине я использовал liveata для навигации и однажды застрял на нем. Ваша публикация и эта статья мне очень помогли. Спасибо! - person Fernando Zabin; 04.10.2019
comment
Ах ... Я наконец понимаю, почему navigateUp дочернего фрагмента зацикливался ... Решил это, используя подход единственного события. - person passerby; 16.10.2019