Grafik navigasi dapat terdiri dari kombinasi berikut:
- Tujuan tunggal, seperti tujuan
<fragment>
. - Grafik bertingkat yang mengenkapsulasi kumpulan tujuan terkait.
- Elemen
<include>
, yang memungkinkan Anda menyematkan file grafik navigasi lain seolah-olah file tersebut disusun bertingkat.
Fleksibilitas ini memungkinkan Anda menggabungkan grafik navigasi yang lebih kecil untuk membentuk grafik navigasi lengkap aplikasi, meskipun grafik navigasi yang lebih kecil tersebut disediakan oleh modul terpisah.
Untuk contoh dalam topik ini, masing-masing
modul fitur difokuskan
berdasarkan satu fitur dan
menyediakan grafik navigasi tunggal yang merangkum semua tujuan
yang diperlukan untuk menerapkan fitur tersebut. Dalam aplikasi produksi, Anda mungkin
memiliki banyak sub-modul pada tingkat yang lebih rendah yang merupakan detail implementasi dari
modul fitur tingkat lebih tinggi ini. Setiap modul fitur ini disertakan, baik secara langsung maupun
tidak langsung, ke dalam
modul app
Anda. Contoh
aplikasi multi-modul yang digunakan dalam dokumen ini
memiliki struktur berikut:
Setiap modul fitur adalah unit mandiri dengan grafik navigasi dan
tujuannya sendiri. Modul app
bergantung pada modul masing-masing, yang menambahkannya sebagai
detail implementasi dalam file build.gradle
, seperti yang ditunjukkan:
Groovy
dependencies { ... implementation project(":feature:home") implementation project(":feature:favorites") implementation project(":feature:settings")
Kotlin
dependencies { ... implementation(project(":feature:home")) implementation(project(":feature:favorites")) implementation(project(":feature:settings"))
Peran modul app
Modul app
bertanggung jawab menyediakan grafik lengkap untuk
aplikasi Anda dan menambahkan NavHost
ke UI. Dalam grafik navigasi modul app
,
Anda dapat mereferensikan grafik library menggunakan
<include>
. Meskipun
penggunaan <include>
secara fungsional sama dengan penggunaan grafik bertingkat,
<include>
mendukung grafik dari modul project lain atau dari project
library, seperti yang ditunjukkan dalam contoh berikut:
<?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_graph"
app:startDestination="@id/home_nav_graph">
<include app:graph="@navigation/home_navigation" />
<include app:graph="@navigation/favorites_navigation" />
<include app:graph="@navigation/settings_navigation" />
</navigation>
Setelah library disertakan dalam grafik navigasi tingkat atas, Anda dapat membuka grafik library sesuai kebutuhan. Misalnya, Anda dapat membuat tindakan untuk membuka grafik setelan dari fragmen di grafik navigasi, seperti yang ditunjukkan:
<?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_graph"
app:startDestination="@id/home_nav_graph">
<include app:graph="@navigation/home_navigation" />
<include app:graph="@navigation/favorites_navigation" />
<include app:graph="@navigation/settings_navigation" />
<fragment
android:id="@+id/random_fragment"
android:name="com.example.android.RandomFragment"
android:label="@string/fragment_random" >
<!-- Launch into Settings Navigation Graph -->
<action
android:id="@+id/action_random_fragment_to_settings_nav_graph"
app:destination="@id/settings_nav_graph" />
</fragment>
</navigation>
Jika beberapa modul fitur perlu mereferensikan sekumpulan
tujuan umum, seperti grafik login, Anda tidak boleh menyertakan
tujuan umum tersebut ke dalam grafik navigasi setiap modul fitur. Sebagai gantinya,
tambahkan tujuan umum tersebut ke grafik navigasi modul app
.
Selanjutnya, setiap modul fitur dapat membuka berbagai modul fitur
untuk membuka tujuan umum tersebut.
Pada contoh sebelumnya, tindakan menentukan tujuan navigasi
@id/settings_nav_graph
. ID ini mengacu pada tujuan yang
ditentukan dalam grafik @navigation/settings_navigation.
yang disertakan.
Navigasi tingkat atas di modul aplikasi
Komponen Navigation menyertakan
class NavigationUI
.
Class ini berisi metode statis yang mengelola navigasi dengan panel
aplikasi atas, panel navigasi, dan navigasi bawah. Jika tujuan tingkat atas
aplikasi Anda terdiri dari elemen UI yang disediakan oleh modul fitur,
modul app
adalah tempat yang alami untuk menempatkan navigasi
tingkat atas dan elemen UI. Karena modul aplikasi bergantung pada
modul fitur yang berkolaborasi, semua tujuannya dapat diakses
dari kode yang ditentukan dalam modul aplikasi Anda. Ini berarti Anda dapat menggunakan
NavigationUI
untuk
menautkan tujuan ke item menu
jika ID item cocok dengan ID tujuan.
Dalam gambar 2, contoh modul app
menentukan
BottomNavigationView
dalam aktivitas utamanya. ID item menu di menu cocok dengan ID grafik navigasi
di grafik library:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@id/home_nav_graph"
android:icon="@drawable/ic_home"
android:title="Home"
app:showAsAction="ifRoom"/>
<item
android:id="@id/favorites_nav_graph"
android:icon="@drawable/ic_favorite"
android:title="Favorites"
app:showAsAction="ifRoom"/>
<item
android:id="@id/settings_nav_graph"
android:icon="@drawable/ic_settings"
android:title="Settings"
app:showAsAction="ifRoom" />
</menu>
Untuk mengizinkan NavigationUI
menangani
navigasi bawah, panggil
setupWithNavController()
dari onCreate()
di class aktivitas utama Anda, seperti yang ditunjukkan dalam
contoh berikut:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment val navController = navHostFragment.navController findViewById<BottomNavigationView>(R.id.bottom_nav) .setupWithNavController(navController) }
Java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); NavHostFragment navHostFragment = (NavHostFragment) supportFragmentManager.findFragmentById(R.id.nav_host_fragment); NavController navController = navHostFragment.getNavController(); BottomNavigationView bottomNav = findViewById(R.id.bottom_nav); NavigationUI.setupWithNavController(bottomNav, navController); }
Setelah kode ini diterapkan, NavigationUI
akan membuka
grafik library yang sesuai saat pengguna mengklik item navigasi bawah.
Perlu diingat bahwa, umumnya menjadi praktik yang buruk bagi modul aplikasi Anda jika memiliki dependensi yang kuat pada tujuan tertentu yang disematkan secara spesifik dalam grafik navigasi modul fitur Anda. Dalam sebagian besar kasus, Anda ingin agar modul aplikasi hanya mengetahui titik entri ke grafik navigasi yang disematkan atau disertakan (ini juga berlaku di luar modul fitur). Jika perlu menautkan ke tujuan sangat spesifik di dalam grafik navigasi library, cara yang lebih disukai untuk melakukannya adalah dengan menggunakan deep link. Penggunaan deep link juga merupakan satu-satunya cara bagi library untuk membuka tujuan di grafik navigasi library lain.
Membuka modul fitur
Pada waktu kompilasi, modul fitur independen tidak dapat saling melihat, sehingga Anda tidak dapat menggunakan ID untuk membuka tujuan di modul lain. Sebagai gantinya, gunakan deep link untuk membuka langsung ke tujuan yang terkait dengan deep link implisit.
Melanjutkan contoh sebelumnya, bayangkan Anda perlu membuka
tujuan yang disusun bertingkat di modul
:feature:settings
dari tombol di modul :feature:home
. Anda dapat melakukannya dengan menambahkan deep link ke tujuan di
grafik navigasi setelan, seperti yang ditampilkan:
<?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/settings_nav_graph"
app:startDestination="@id/settings_fragment_one">
...
<fragment
android:id="@+id/settings_fragment_two"
android:name="com.example.google.login.SettingsFragmentTwo"
android:label="@string/settings_fragment_two" >
<deepLink
app:uri="android-app://example.google.app/settings_fragment_two" />
</fragment>
</navigation>
Lalu, tambahkan kode berikut ke onClickListener
tombol di fragmen
layar utama:
Kotlin
button.setOnClickListener { val request = NavDeepLinkRequest.Builder .fromUri("android-app://example.google.app/settings_fragment_two".toUri()) .build() findNavController().navigate(request) }
Java
button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { NavDeepLinkRequest request = NavDeepLinkRequest.Builder .fromUri(Uri.parse("android-app://example.google.app/settings_fragment_two")) .build(); NavHostFragment.findNavController(this).navigate(request); } });
Tidak seperti bernavigasi menggunakan ID tujuan atau tindakan, Anda dapat bernavigasi ke URI apa pun dalam grafik apa pun, bahkan di seluruh modul.
Saat bernavigasi menggunakan URI, data sebelumnya tidak direset. Perilaku ini tidak seperti navigasi deep link eksplisit, yang mengganti data sebelumnya saat bernavigasi.