<androidx.fragment.app.FragmentContainerView> vs <fragment> як перегляд для NavHost


9

При використанні androidx.fragment.app.FragmentContainerViewяк navHost замість звичайного fragmentдодатка не вдається переміститися до пункту призначення після зміни орієнтації.

Я отримую таку помилку: java.lang.IllegalStateException: no current navigation node

Чи є готча, яку я повинен знати про її правильне використання або мій спосіб використання компонентів nav невірний?

Прості дії xml з видом:


...
    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        app:navGraph="@navigation/nav_simple" />
...

Код навігації:

<?xml version="1.0" encoding="utf-8"?>
<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"
    android:id="@+id/nav_legislator.xml"
    app:startDestination="@id/initialFragment">

    <fragment
        android:id="@+id/initialFragment"
        android:name="com.example.fragmenttag.InitialFragment"
        android:label="Initial Fragment"
        tools:layout="@layout/initial_fragment">
        <action
            android:id="@+id/action_initialFragment_to_destinationFragment"
            app:destination="@id/destinationFragment" />
    </fragment>
    <fragment
        android:id="@+id/destinationFragment"
        android:name="com.example.fragmenttag.DestinationFragment"
        android:label="Destination Fragment"
        tools:layout="@layout/destination_fragment" />

</navigation>

Ось github repo, де ви можете легко відтворити помилку: https://github.com/dmytroKarataiev/navHostBug


Потрібно поставити <fragmentв а FragmentContainerView.
EpicPandaForce

Відповіді:


18

no current navigation nodeПомилка виникає , коли немає встановленого графіка , і ви намагаєтеся викликати navigate(). Якщо вона виникає лише під час використання FragmentContainerViewта після зміни конфігурації, це буде пов’язано з цією помилкою , яка виправлена ​​та запланована до випуску за допомогою Navigation 2.2.0-rc03.

Щоб вирішити цю проблему, можна або переключитися назад, <fragment>або видалити, app:navGraph="@navigation/nav_simple"а натомість зателефонувати navController.setGraph(R.navigation.nav_simple).


Я фактично спробував такий підхід, і я отримав абсолютно таку ж помилку. Чи зможете ви перевірити репо і спробувати змусити його працювати з таким підходом?
Дмитро Каратаєв

Також цей збій трапляється лише після зміни орієнтації. Це працює в усі інші часи.
Дмитро Каратаєв

Я насправді думаю, що це не та сама помилка, nav-контролер не є нульовим у моєму запитанні, але його зворотний стек порожній, а графік - нульовим.
Дмитро Каратаєв

Ага, так, це дуже важлива інформація. Здається, це те, що ви переживаєте, це інша проблема . Я оновив свою відповідь, щоб обговорити, що відбувається в цьому питанні.
ianhanniballake

Дякую, ідеально.
Дмитро Каратаєв

0

Я не бачу якихось - яких пояснень , чому замінити Fragment вид з FragmentContainerView . Ось чому додайте цю відповідь:

Один із поширених шаблонів для розміщення фрагментів у діяльності - це використання FrameLayout. Android-спільнота займається цим вже роками, але це зараз зміниться. Команда androidx представила цей новий погляд під назвою FragmentContainerView, щоб зробити це для вас.

Все, що вам потрібно зробити, це замінити FrameLayout на FragmentContainerView, і все повинно працювати нестандартно, вам не потрібно буде нічого змінювати під час обробки фрагментних транзакцій.

Переваги, отримані тут, - це вдосконалене управління тим, що називається впорядкуванням z для фрагментів. Ось приклад, який вони використовували, але в основному це означає, наприклад, що вихід і введення переходів між двома фрагментами не перетинатимуться один з одним. Замість цього FragmentContainerView запустить анімацію виходу спочатку, а потім анімацію введення.

Якщо ви запитуєте, чи може це замінити тег? то відповідь - так. Все, що вам потрібно зробити, - це додати android: name = "your_class_name" під час визначення FragmentContainerView, і він використовуватиме FragmentTransaction під кришкою, щоб створити та показати ваш фрагмент. Це означає, що згодом ви можете використовувати операції з фрагментами для їх заміни.

Джерело

Документи Android


1
Я не вірю, що це відповідає на запитання автора.
AlgoRyan

Це ще гарна додаткова інформація.
Rvb84
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.