Halo semuanya! Saya ingin berbicara tentang fitur dalam karya 
Navigasi Arsitektur Komponen , karena itu saya mempunyai kesan ambigu perpustakaan.
Artikel ini bukan panduan langkah demi langkah, ini menghilangkan detail implementasi untuk fokus pada poin-poin utama. Ada banyak kasus penggunaan 
serupa di Internet (ada juga terjemahan) - mereka akan membantu Anda berkenalan dengan perpustakaan. Juga, sebelum membaca, saya mengusulkan untuk mempelajari 
dokumentasinya .
 Saya harus mengatakan segera bahwa saya pasti menganggap perpustakaan bermanfaat dan tidak mengecualikan kemungkinan penyalahgunaan, tetapi saya mungkin mencoba semuanya sebelum menulis artikel ini.
Saya harus mengatakan segera bahwa saya pasti menganggap perpustakaan bermanfaat dan tidak mengecualikan kemungkinan penyalahgunaan, tetapi saya mungkin mencoba semuanya sebelum menulis artikel ini.Jadi, berikut adalah skenario dalam implementasi yang harapan untuk fungsi tidak sesuai dengan kenyataan dalam implementasi:
- beralih antar item menu di laci navigasi
- penemuan Kegiatan baru dengan grafik navigasinya
- meneruskan parameter ke startDestination
Beralih di antara item menu
Ini adalah salah satu fitur yang mempengaruhi keputusan untuk menggunakan Komponen Navigasi.
Anda hanya perlu membuat id item menu identik
activity_main_drawer.xml<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:showIn="navigation_view"> <group android:checkableBehavior="single"> <item android:id="@+id/importFragment" android:icon="@drawable/ic_menu_camera" android:title="Import"/> <item android:id="@+id/galleryFragment" android:icon="@drawable/ic_menu_gallery" android:title="Gallery"/> <item android:id="@+id/slideshowFragment" android:icon="@drawable/ic_menu_slideshow" android:title="Slideshow"/>  
 dan id layar (tujuan dalam grafik navigasi)
mobile_navigation.xml <?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/mobile_navigation" app:startDestination="@id/importFragment"> <fragment android:id="@+id/importFragment" android:name="com.xiii.navigationapplication.ImportFragment" android:label="fragment_import" tools:layout="@layout/fragment_import"/> <fragment android:id="@+id/galleryFragment" android:name="com.xiii.navigationapplication.GalleryFragment" android:label="fragment_gallery" tools:layout="@layout/fragment_gallery"/> <fragment android:id="@+id/slideshowFragment" android:name="com.xiii.navigationapplication.SlideshowFragment" android:label="fragment_slideshow" tools:layout="@layout/fragment_slideshow"/> </navigation> 
 maka Anda perlu mengaitkan menu dengan pengontrol navigasi:
MainActivity.kt class MainActivity : AppCompatActivity() { private val navController by lazy(LazyThreadSafetyMode.NONE) { Navigation.findNavController(this, R.id.nav_host_fragment) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) setSupportActionBar(toolbar)  
 Navigasi di menu telah berfungsi - bukankah itu keajaiban?!
Perhatikan "hamburger" (ikon menu), saat beralih di antara item menu, ia mengubah statusnya menjadi tombol "kembali". Perilaku ini tampak 
tidak biasa (seperti 
familier - seperti dalam aplikasi pasar bermain) dan, untuk sementara waktu, saya mencoba mencari tahu apa yang salah?
Itu saja! Setelah membaca dokumentasi tentang prinsip-prinsip navigasi (yaitu, poin 
dua dan 
tiga ), saya menyadari bahwa "hamburger" ditampilkan hanya untuk 
startDestination , atau lebih tepatnya, dengan cara ini: tombol kembali ditampilkan untuk semua orang kecuali 
startDestination . Situasi dapat diubah dengan menerapkan berbagai trik dalam berlangganan ( 
addOnNavigatedListener () ) untuk mengubah 
tujuan , tetapi mereka bahkan tidak boleh dijelaskan. Ini berfungsi seperti ini, Anda harus menyetujui.
Membuka Kegiatan baru
Aktivitas dapat bertindak sebagai 
host navigasi dan, pada saat yang sama, dalam grafik navigasi dapat bertindak sebagai salah satu 
tujuan . Membuka suatu Kegiatan tanpa grafik navigasi bersarang berfungsi 
seperti yang diharapkan , mis. Panggilan:
 navController.navigate(R.id.editActivity) 
akan melakukan transisi (seperti dalam kasus fragmen) dan membuka Aktivitas yang diminta.
Jauh lebih menarik untuk mempertimbangkan kasus ketika Aktivitas target itu sendiri bertindak sebagai 
host navigasi , yaitu opsi 2 dari 
dokumentasi :

Sebagai contoh, mari kita lihat Kegiatan untuk menambahkan catatan. Ini akan 
berisi fragmen utama dengan 
bidang input 
EditFragment , itu akan menjadi 
StartDestination dalam grafik navigasi. Mari kita asumsikan bahwa ketika mengedit kita perlu melampirkan foto, untuk ini kita akan pergi ke 
PhotoFragment untuk mendapatkan gambar dari kamera. Grafik navigasi akan terlihat seperti ini:
edit_navigation.xml <?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/edit_navigation" app:startDestination="@id/editFragment"> <fragment android:id="@+id/editFragment" android:name="com.xiii.navigationapplication.ui.edit.EditFragment" android:label="fragment_edit" tools:layout="@layout/fragment_edit"> <action android:id="@+id/action_editFragment_to_photoFragment" app:destination="@id/photoFragment"/> </fragment> <fragment android:id="@+id/photoFragment" android:name="com.xiii.navigationapplication.ui.edit.PhotoFragment" android:label="fragment_photo" tools:layout="@layout/fragment_photo"/> </navigation> 
 EditActivity tidak jauh berbeda dari 
MainActivity . Perbedaan utama adalah bahwa tidak ada menu di 
EditActivity :
EditActivity.kt class EditActivity : AppCompatActivity() { private val navController by lazy(LazyThreadSafetyMode.NONE) { Navigation.findNavController(this, R.id.nav_host_fragment) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_edit) setSupportActionBar(toolbar) //    ""  toolbar NavigationUI.setupWithNavController(toolbar, navController) } override fun onSupportNavigateUp() = navController.navigateUp() fun takePhoto(view: View) { navController.navigate(R.id.action_editFragment_to_photoFragment) } } 
 Aktivitas terbuka, navigasi di dalamnya berfungsi:
Sekali lagi, perhatikan tombol navigasi di bilah alat - pada awal 
EditFragment tidak ada tombol "Kembali ke aktivitas Orang 
Tua " (tapi saya ingin). Dari sudut pandang dokumentasi, semuanya legal di sini: grafik navigasi baru, nilai 
startDestination baru, tombol "Kembali" tidak ditampilkan di 
startDestination , akhir.
Bagi mereka yang ingin kembali ke 
perilaku biasa dengan aktivitas orang tua , sambil mempertahankan fungsionalitas untuk beralih antar fragmen, saya dapat menawarkan pendekatan 
kruk ini:
1. Tentukan Aktivitas induk dalam manifes <activity android:name=".EditActivity" android:parentActivityName=".MainActivity" android:theme="@style/AppTheme.NoActionBar">  <meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".MainActivity" /> </activity> 
 2. Tambahkan langganan di mana kami akan mengganti id startDestination class EditActivity : AppCompatActivity() { private val navController by lazy(LazyThreadSafetyMode.NONE) { Navigation.findNavController(this, R.id.nav_host_fragment) } private var isStartDestination = true override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_edit) setSupportActionBar(toolbar) val startDestinationId = navController.graph.startDestination //    id,  NavigationUI.ActionBarOnNavigatedListener     //      destination    startDestination navController.addOnNavigatedListener { controller, destination -> isStartDestination = destination.id == startDestinationId // R.id.fake_start_destination  id        controller.graph.startDestination = if (isStartDestination) R.id.fake_start_destination else startDestinationId } //    ""  toolbar NavigationUI.setupActionBarWithNavController(this, navController) } override fun onSupportNavigateUp(): Boolean { //  startDestination      Navigation Component return if (isStartDestination) super.onSupportNavigateUp() else navController.navigateUp() } fun takePhoto(view: View) { navController.navigate(R.id.action_editFragment_to_photoFragment) } } 
 Berlangganan diperlukan agar untuk 
NavigationUI.ActionBarOnNavigatedListener semua tujuan tidak startDestination . Dengan demikian, 
NavigationUI.ActionBarOnNavigatedListener tidak akan menyembunyikan tombol navigasi (lihat sumber untuk detail). Tambahkan ke ini pemrosesan 
onSupportNavigateUp () secara teratur di 
startDestination dan dapatkan yang kita inginkan.
Perlu dikatakan bahwa solusinya jauh dari ideal, jika hanya karena itu adalah intervensi yang tidak terlihat dalam perilaku perpustakaan. Saya percaya bahwa masalah dapat muncul ketika menggunakan 
tautan dalam (saya belum mengujinya).
Melewati parameter ke startDestination
Komponen Navigasi memiliki 
mekanisme untuk meneruskan parameter dari satu 
tujuan ke tujuan lain. Bahkan ada 
alat untuk memastikan keamanan tipe melalui pembuatan kode (tidak buruk).
Sekarang kita akan menganalisis kasus ini, karena itu saya tidak dapat menempatkan lima solid untuk fungsional ini.
Mari kita kembali ke 
EditActivity , skenario yang cukup akrab ketika satu Kegiatan digunakan untuk membuat dan mengedit objek. Saat Anda membuka objek untuk diedit di Aktivitas, Anda perlu mentransfer, misalnya, id objek - mari kita lakukan secara teratur:
1. Tambahkan parameter ke grafik untuk EditActivitySaya menambahkan parameter langsung ke elemen root dari grafik (navigasi), tetapi dapat ditambahkan ke fragmen target. Dari ini, hanya metode mendapatkan parameter yang akan berubah.
 <?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/edit_navigation" app:startDestination="@id/editFragment"> <argument android:name="id" app:argType="integer"/> <fragment android:id="@+id/editFragment" android:name="com.xiii.navigationapplication.ui.edit.EditFragment" android:label="fragment_edit" tools:layout="@layout/fragment_edit"> <action android:id="@+id/action_editFragment_to_photoFragment" app:destination="@id/photoFragment"/> </fragment> <fragment android:id="@+id/photoFragment" android:name="com.xiii.navigationapplication.ui.edit.PhotoFragment" android:label="fragment_photo" tools:layout="@layout/fragment_photo"/> </navigation> 
 2. Tambahkan aksi ke grafik utamaSaya menambahkan menambahkan dan mengedit tindakan ke salah satu fragmen, sehingga hanya akan tersedia dari itu.
 <?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/mobile_navigation" app:startDestination="@id/importFragment"> <fragment android:id="@+id/importFragment" android:name="com.xiii.navigationapplication.ImportFragment" android:label="fragment_import" tools:layout="@layout/fragment_import"> <action android:id="@+id/add" app:destination="@id/editActivity"> <argument android:name="id" app:argType="integer" android:defaultValue="0"/> </action> <action android:id="@+id/edit" app:destination="@id/editActivity"> <argument android:name="id" app:argType="integer"/> </action> </fragment> <fragment android:id="@+id/galleryFragment" android:name="com.xiii.navigationapplication.GalleryFragment" android:label="fragment_gallery" tools:layout="@layout/fragment_gallery"/> <fragment android:id="@+id/slideshowFragment" android:name="com.xiii.navigationapplication.SlideshowFragment" android:label="fragment_slideshow" tools:layout="@layout/fragment_slideshow"/> <activity android:id="@+id/editActivity" android:name="com.xiii.navigationapplication.EditActivity" android:label="activity_edit" tools:layout="@layout/activity_edit"/> </navigation> 
 3. Siapkan parameter dan minta transisiDalam contoh ini, 
ImportFragmentDirections adalah kelas safe-args yang dibuat secara otomatis.
 val direction = ImportFragmentDirections.edit(123 ) navController.navigate(direction) 
 3. Dapatkan id dalam fragmen class EditFragment : Fragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {  
 Anda, tentu saja, memperhatikan fitur-fitur untuk mendapatkan parameter di 
EditFragment . Ini berfungsi karena tindakan edit (dari titik 1) meneruskan argumen ke 
EditActivity , dan untuk sebagian alasannya, adalah 
serakah bahwa tidak meneruskannya ke grafik (misalnya, dengan memanggil 
navController.graph.setDefaultArguments () ). Fitur ini dapat dielakkan dengan menyiapkan 
pengontrol navigasi secara manual. Satu cara dijelaskan pada 
StackOwerflow .
Mungkin kesulitan terbesar akan muncul ketika digunakan secara bersamaan sebagai 
startDestination dan 
tujuan yang biasa. Yaitu, ketika meneruskan dan meneruskan parameter ke 
startDestination dari 
tujuan lain mana pun 
dari grafik ini, fragmen harus menentukan secara independen di mana mengekstrak parameter dari: dari argumen atau dari intent.extras. Ini harus diingat ketika merancang transisi dengan melewati parameter.
Meringkas, saya ingin mencatat bahwa saya sendiri belum berhenti menggunakan perpustakaan dan, meskipun ada 
kekurangan fitur yang terdaftar, saya merasa cukup berguna untuk merekomendasikan untuk digunakan. Saya sangat berharap bahwa dalam rilis berikutnya situasinya akan berubah, setidaknya dengan transfer parameter ke 
startDestination .
Terima kasih atas perhatian anda Kode kerja Anda!
Sumber untuk artikel ini diposting di 
GitHub .