<androidx.fragment.app.FragmentContainerView> vs <fragment> sebagai tampilan untuk NavHost

9

Saat menggunakan androidx.fragment.app.FragmentContainerViewsebagai navHost bukan fragmentaplikasi biasa tidak dapat menavigasi ke tujuan setelah perubahan orientasi.

Saya mendapatkan kesalahan berikut: java.lang.IllegalStateException: no current navigation node

Apakah ada gotcha yang harus saya ketahui untuk menggunakannya dengan benar atau apakah cara saya menggunakan komponen nav salah?

Aktivitas sederhana xml dengan tampilan:


...
    <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" />
...

Kode navigasi:

<?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>

Berikut adalah repo github tempat Anda dapat mereproduksi bug dengan mudah: https://github.com/dmytroKarataiev/navHostBug

Dmytro Karataiev
sumber
Anda perlu memasukkan <fragmentke dalam FragmentContainerView.
EpicPandaForce

Jawaban:

18

The no current navigation nodekesalahan terjadi ketika tidak ada grafik set dan Anda mencoba untuk memanggil navigate(). Jika itu hanya terjadi ketika Anda menggunakan FragmentContainerViewdan setelah perubahan konfigurasi, maka ini akan terkait dengan bug ini , yang diperbaiki dan dijadwalkan untuk rilis dengan Navigasi 2.2.0-rc03.

Untuk mengatasi masalah ini, Anda dapat beralih kembali <fragment>atau menghapus app:navGraph="@navigation/nav_simple"dan alih-alih menelepon navController.setGraph(R.navigation.nav_simple).

ianhanniballake
sumber
Saya benar-benar mencoba pendekatan ini dan saya mendapatkan kesalahan yang persis sama. Apakah Anda dapat memeriksa repo dan mencoba membuatnya bekerja dengan pendekatan ini?
Dmytro Karataiev
Juga, kerusakan ini terjadi hanya setelah perubahan orientasi. Ini bekerja sepanjang waktu lainnya.
Dmytro Karataiev
Saya benar-benar berpikir ini bukan kesalahan yang sama, nav controller bukan nol dalam pertanyaan saya, tetapi tumpukan kembali kosong dan grafiknya nol.
Dmytro Karataiev
Ah, ya, itu informasi yang cukup penting, Kedengarannya seperti yang Anda alami adalah masalah lain ini . Saya telah memperbarui jawaban saya untuk membahas apa yang terjadi dalam masalah itu.
ianhanniballake
Terima kasih, sempurna.
Dmytro Karataiev
0

Saya tidak melihat penjelasan mengapa mengganti Fragmen tampilan dengan FragmentContainerView . Inilah sebabnya mengapa tambahkan jawaban ini:

Salah satu pola umum untuk meng-host fragmen dalam suatu aktivitas adalah dengan menggunakan FrameLayout. Komunitas Android telah melakukan ini selama bertahun-tahun tetapi ini akan berubah sekarang. Tim androidx memperkenalkan tampilan baru ini yang disebut FragmentContainerView untuk melakukan ini untuk Anda.

Yang harus Anda lakukan adalah mengganti FrameLayout Anda dengan FragmentContainerView dan semuanya akan berjalan lancar, Anda tidak perlu mengubah apa pun dalam cara Anda menangani transaksi fragmen.

Manfaat yang diperoleh di sini adalah penanganan yang lebih baik dari apa yang disebut pemesanan-z untuk fragmen. Berikut adalah contoh yang mereka gunakan, tetapi pada dasarnya ini berarti, misalnya, bahwa transisi keluar dan masuk antara dua fragmen tidak akan tumpang tindih satu sama lain. Alih-alih, FragmentContainerView ini akan memulai animasi keluar terlebih dahulu kemudian masukkan animasi.

Jika Anda bertanya, apakah ini dapat mengganti tag? maka jawabannya adalah ya. Yang harus Anda lakukan adalah menambahkan android: name = "your_class_name" ketika mendefinisikan FragmentContainerView dan itu akan menggunakan FragmentTransaction di bawah tenda untuk membangun dan menampilkan fragmen Anda. Ini berarti Anda dapat menggunakan transaksi fragmen nanti untuk menggantinya.

Sumber

Android Docs

Michalsx
sumber
1
Saya tidak percaya ini menjawab pertanyaan yang diajukan penulis.
AlgoRyan
Itu masih informasi tambahan yang bagus.
Rvb84