Правильное использование компонента навигации с view pager2 и вложенной навигацией - PullRequest
0 голосов
/ 06 мая 2020

Я пытаюсь создать следующую структуру представления / навигацию с помощью компонента навигации ViewPager2 + FragmentStateAdapter +.

Предварительные условия: архитектура одного действия с одним графом навигации

1. Фрагмент A содержит пейджер просмотра. Пейджер просмотра использует FragmentStateAdapter.

2. Фрагмент B создается через FragmentStateAdapter ("живет" в пейджере представления).

3. Фрагмент C - к нему нужно перейти из фрагмента B. -> Вот где проблема.


Подход 1: ViewPager2 + FragmentStateAdapter + навигация, объявленная из фрагмента B

    <fragment
        android:id="@+id/fragmentA"
        android:name="com.abc.FragmentA"
        android:label="FragmentA" />

    <fragment
        android:id="@+id/fragmentB"
        android:name="com.abc.FragmentB"
        android:label="FragmentB">
        <action
            android:id="@+id/to_fragmentC"
            app:destination="@id/fragmentC" />
    </fragment>

    <fragment
        android:id="@+id/fragmentC"
        android:name="com.abc.FragmentC"
        android:label="FragmentC" />

FragmentB выполняет:

 FragmentBDirections
            .toFragmentC()
            .let { findNavController().navigate(it) }

Результат:

App crash
java.lang.IllegalArgumentException: navigation destination com.abc:id/to_fragmentC is unknown to this NavController

Подход 2: ViewPager2 + FragmentStateAdapter + навигация, объявленная из фрагмента A

    <fragment
        android:id="@+id/fragmentA"
        android:name="com.abc.FragmentA"
        android:label="FragmentA" >
        <action
            android:id="@+id/to_fragmentC"
            app:destination="@id/fragmentC" />
    </fragment>

    <fragment
        android:id="@+id/fragmentB"
        android:name="com.abc.FragmentB"
        android:label="FragmentB">
    </fragment>

    <fragment
        android:id="@+id/fragmentC"
        android:name="com.abc.FragmentC"
        android:label="FragmentC" />

FragmentB выполняет:

 FragmentADirections
            .toFragmentC()
            .let { findNavController().navigate(it) }

Результат:

App navigates to FragmentC, but when i hit the back button , it crashes with :
java.lang.IllegalArgumentException
        at androidx.core.util.Preconditions.checkArgument(Preconditions.java:36)
        at androidx.viewpager2.adapter.FragmentStateAdapter.onAttachedToRecyclerView(FragmentStateAdapter.java:132)
        at androidx.recyclerview.widget.RecyclerView.setAdapterInternal(RecyclerView.java:1209)
        at androidx.recyclerview.widget.RecyclerView.setAdapter(RecyclerView.java:1161)
        at androidx.viewpager2.widget.ViewPager2.setAdapter(ViewPager2.java:461)
        at com.abc.FragmentA.viewCreated(FragmentA.kt:69)


Подход 3: ViewPager + FragmentStatePagerAdapter (не рекомендуется) + навигация, объявленная из фрагмента B

Тот же результат, что и подход 1.


Подход 4: ViewPager + FragmentStatePagerAdapter (устарел) + навигация, объявленная из фрагмента A

Этот действительно работает. Кроме того, навигация назад работает нормально.

Проблема здесь в том, что:

  • Навигация должна быть определена для каждого родительского фрагмента FragmentB -> не очень масштабируемый
  • Использование устаревшего адаптера

Если кто-нибудь знает какое-нибудь элегантное решение этой проблемы, я был бы очень рад любым подсказкам.

Спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...