NavController.OnDestinationChangedListener передает destination.id, не соответствующий сработавшему идентификатору действия навигации - PullRequest
3 голосов
/ 14 марта 2020

В моем проекте Android у меня есть очень простой навигационный график, включающий два фрагмента: Master и Detail:

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   app:startDestination="@id/wordsListFragment">

    <fragment
        android:id="@+id/wordsListFragment"
        android:name="com.***.presentation.view.WordsListFragment"
        android:label="List"
        tools:layout="@layout/words_list_fragment">
        <action
            android:id="@+id/action_wordsListFragment_to_wordDetailsFragment"
            app:destination="@id/wordDetailsFragment" />
    </fragment>
    <fragment
        android:id="@+id/wordDetailsFragment"
        android:name="com.***.presentation.view.WordDetailsFragment"
        android:label="Details"
        tools:layout="@layout/word_details_fragment" />
</navigation>

Сама навигация прекрасно работает в обоих направлениях, включая поведение "Назад". В этом проекте у меня есть одно действие, где я реализую OnDestinationChangedListener. Все это согласно следующей документации от Google: Обновление пользовательского интерфейса NavController

Я вызываю следующий метод, когда пользователь нажимает на элемент списка (находясь в главном фрагменте):

findNavController().navigate(R.id.action_wordsListFragment_to_wordDetailsFragment, null)

Тогда в родительском действии у меня есть следующая реализация:

private fun setupNavController() {
    navigationController = findNavController(R.id.nav_mainhost_fragment_container)
    navigationController.addOnDestinationChangedListener(mainDestinationChangedListener)
    appBarConfiguration = AppBarConfiguration(navigationController.graph)
    setupActionBarWithNavController(navigationController, appBarConfiguration)
}

, и это объект слушателя:

private val mainDestinationChangedListener = 
NavController.OnDestinationChangedListener { controller, destination, arguments ->        

if (destination.id == R.id.action_wordsListFragment_to_wordDetailsFragment) {
        actionBar?.hide()
    } else {
        actionBar?.show()
    }
}

, но destination.id не совпадает R.id.action_wordsListFragment_to_wordDetailsFragment

Я пытался очистить проект, очистить кэш IDE, кэш градла, но сгенерированные идентификаторы все равно не совпадают. Я также пытался использовать Навигацию через Safe Args:

val action = WordsListFragmentDirections.actionWordsListFragmentToWordDetailsFragment()
findNavController().navigate(action)

, но результаты в данном слушателе всегда одинаковы (то есть не совпадают).

Некоторые значения отладки:

findNavController().navigate(1000021) //R.id.action_wordsListFragment_to_wordDetailsFragment

, но следующий вызов в стеке имеет другое значение: enter image description here, что также соответствует значениям destination.id, переданным в OnDestinationChangedListener:

destination.id //2131231018

Любые намеки с вашей стороны приветствуются. Я просто хочу распознать пункт назначения или идентификатор действия и соответствующим образом настроить панель инструментов.

1 Ответ

0 голосов
/ 14 марта 2020

Вы сравниваете fragId с actionId , поэтому здесь всегда ложно

здесь if (destination.id == R.id.action_wordsListFragment_to_wordDetailsFragment)

Как destination.id равно фрагментId и R.id.action_wordsListFragment_to_wordDetailsFragment - это actionId

Чтобы это работало, вам нужно сравнить два фрагмента идентификаторов, например

if (destination.id == R.id.wordDetailsFragment)

* Редактировать

Сначала Вы должны найти свой navControler, а затем прослушать изменение его назначения.

val navController = findNavController(this,R.id.nav_host_fragment)// this maybe change
navController.addOnDestinationChangedListener { controller, destination, arguments ->
   if(destination.id == R.id.wordDetailsFragment) {
       actionBar?.hide()
   } else {
       actionBar?.show()
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...