Передача аргумента между двумя фрагментами, каждый из которых представлен в другом навигационном графе.

Использование компонента навигации 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)

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

Надеюсь, это поможет кому-то.