Передача аргумента между двумя фрагментами, каждый из которых представлен в другом навигационном графе.
Использование компонента навигации Android. У меня есть два навигационных графика (каждый со своим собственным потоком), скажем, навигационные графы A и B. Я успешно перемещаюсь от A к B, но мне не удается передать аргумент из последнего фрагмента, включенного в граф A, Фрагмент старта, который принадлежит графу Б.
Я могу передавать аргументы между фрагментами, которые принадлежат одному и тому же графу, но функция для установки аргументов не была сгенерирована при переходе между навигационными графами.
Я пытаюсь достичь этого, используя safeargs.
Вот код навигационных графиков:
Навигационный график A:
<navigation android:id="@+id/nav_graph_a"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:startDestination="@id/fragment1">
<fragment
android:id="@+id/fragment1"
android:name="com.mypackage.fragments.Fragment1"
android:label="Fragment1">
<action
android:id="@+id/action_fragment1_to_fragment2"
app:destination="@id/fragment2"/>
</fragment>
<fragment
android:id="@+id/fragment2"
android:name="com.mypackage.fragments.Fragment2"
android:label="Fragment2">
<argument
android:name="thisArgumentAlwaysArrive"
android:defaultValue="null"
app:argType="string"/>
<action
android:id="@+id/action_fragment2_to_nav_graph_b"
app:destination="@id/nav_graph_b"/>
</fragment>
<include app:graph="@navigation/nav_graph_b"/>
Навигационный график B:
<navigation android:id="@+id/nav_graph_b"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:startDestination="@id/fragment3">
<fragment
android:id="@+id/fragment3"
android:name="com.mypackage.fragments.Fragment3"
android:label="Fragment3">
<argument
android:name="thisArgumentNeverArrive"
app:argType="string"/>
</fragment>
Есть идеи, как этого добиться?
2 ответа
Как указано в документации :
Примечание. Безопасные аргументы не поддерживают навигацию между модулями, так как нет прямого действия к месту назначения. В предыдущем примере, несмотря на то, что класс Directions будет создан для целевого пункта назначения в настройках, вы не сможете получить доступ к созданному классу из пути к классам модуля списка.
Но вы можете использовать пакет вместо nav_args следующим образом:
Из
FristFragmentDirections.actionFirstFragmentToSecondFragment(your_parameter).let { action ->
findNavController().navigate(action)
}
К
FristFragmentDirections.actionFirstFragmentToSecondFragment().let { action ->
findNavController().navigate(
action.actionId,
Bundle().apply { putString("parameter_key", your_parameter) }
)
}
Safe Args - это плагин для Gradle, который создает классы ClassArgs для пунктов назначения. Контроллер по умолчанию обеспечивает способ перехода к другому NavGraph, в этом случае есть реализация навигатора под названием NavGraphNavigator. Этот навигатор предоставляет вамnavigate(NavGraph destination,Bundle args)
функция, которая передает аргументы начальному фрагменту.
Итак, лучший способ, который я нашел, сделать то, что вы пытаетесь достичь, - это использовать сгенерированный класс для создания пакета с необходимыми аргументами.
var myBundle = YourFragmentIdInNavGraphArgs.Builder(var args..).toBundle()
а затем используйте NavController по умолчанию для перехода к пункту назначения navGraph, подобному этому.
view.findNavController().navigate(R.id.your_action_to_nav_graph_id,myBundle)
реализация навигатора позаботится о передаче аргументов стартовому фрагменту в пункте назначения.
Надеюсь, это поможет кому-то.