Компонентная навигация, извлечение из бэкстека с аргументами

Допустим, у меня есть три фрагмента: A, B, C;

A -> B <-> C

Между B и C это круговая связь. Для фрагментов B или C требуется arguments, например

     val args = Bundle()

     args.putString("StringKeyBC", argValueBtoC)       
     findNavController().navigate(R.id.action_fragmentB_to_fragmentC, args, null)

     args.putString("StringKeyCB", argValueCtoB)       
     findNavController().navigate(R.id.action_fragmentC_to_fragmentB, args, null)

Проблема в том, что каждый раз, когда я перемещаюсь между B и C, фрагменты добавляются в задний стек, а я этого не хочу. Если фрагмент уже находится в стеке, я хочу просто вытащить его, но если я использую popBackStack, я больше не могу добавлять аргументы:

public boolean popBackStack(@IdRes int destinationId, boolean inclusive)

Итак, как я могу постоянно переключаться между двумя фрагментами, не добавляя их каждый раз в стек?




Ответы (1)


Вы можете извлекать фрагменты из заднего стека, просто добавляя атрибут popUpTo к действию навигации. Таким образом вы перемещаетесь, используя действие с аргументами, но с поведением возврата стека.

Например, вы можете добавить к действию action_fragmentC_to_fragmentB атрибут app:popUpTo="@+id/fragmentB". Таким образом, вы будете извлекать фрагментC из backstack каждый раз, когда переходите от фрагментаC к фрагменту B.

См. документы с примерами здесь.

Есть еще один вариант, который, вероятно, является накладным расходом для описанного вами случая, но он позволяет использовать метод popBackStack и отправлять аргументы - используя подход «вернуться с результатом». Для этого фрагменты должны реализовывать интерфейс (обратный вызов) с методом, который получает пакет. Используйте addOnBackStackChangedListener в диспетчере фрагментов, чтобы запустить этот метод, предоставив все необходимые данные после вызова popBackStack. (Описано здесь в разделе «Как вернуться к результату?»: https://medium.com/google-developer-experts/using-navigation-architecture-component-in-a-large-bank-app-ac84936a42c2 , и с немного другой реализацией здесь: https://medium.com/@zawadz88/david-v%C3%A1vra-thank-you-for-this-great-article-ae3e602b880a)

person Roman Potapov    schedule 21.08.2019
comment
И, конечно же, вы можете использовать совместно используемую ViewModel, как предлагает Google, чтобы обеспечить доступность необходимых данных для фрагментов B и C вместо передачи аргументов напрямую от фрагмента к фрагменту. Таким образом, вы снова можете продолжать использовать popBackStack. - person Roman Potapov; 21.08.2019