NavController
menyimpan "data sebelumnya" yang berisi tujuan pengguna
telah dikunjungi. Saat pengguna bernavigasi di dalam aplikasi Anda,
NavController
menambah dan menghapus tujuan ke dan dari data sebelumnya.
Dalam stack, data sebelumnya adalah struktur data "masuk terakhir, keluar pertama". Tujuan
Oleh karena itu, NavController
mendorong item ke dan memunculkan item dari bagian atas
{i>stack<i}.
Perilaku dasar
Berikut ini fakta inti yang harus Anda pertimbangkan terkait perilaku data sebelumnya:
- Tujuan pertama: Saat pengguna membuka aplikasi,
NavController
mendorong tujuan pertama ke bagian atas data sebelumnya. - Mendorong ke stack: Setiap panggilan
NavController.navigate()
mendorong tujuan yang diberikan ke bagian atas stack. - Memunculkan tujuan teratas: Mengetuk Up atau Back akan memanggil
NavController.navigateUp()
danNavController.popBackStack()
. Metode tersebut memunculkan tujuan teratas dari stack. Lihat halaman Prinsip Navigasi untuk mengetahui informasi selengkapnya tentang perbedaan antara Up dan Back.
Mengembalikan
Metode NavController.popBackStack()
mencoba memunculkan tujuan saat ini
dari data sebelumnya dan menavigasi ke tujuan sebelumnya. Metode ini
secara efektif mengembalikan pengguna ke satu langkah sebelumnya di histori navigasi. Metode ini menampilkan
boolean yang menunjukkan apakah metode tersebut berhasil kembali ke tujuan.
Mengembalikan ke tujuan tertentu
Anda juga dapat menggunakan popBackStack()
untuk menavigasi ke tujuan tertentu. Untuk melakukannya,
gunakan salah satu overload. Ada beberapa overload yang memungkinkan Anda meneruskan ID,
seperti bilangan bulat id
atau string route
. Overload ini membawa
pengguna ke tujuan yang terkait dengan ID yang diberikan. Yang terpenting,
overload tersebut mengembalikan semua tumpukan di atas tujuan tersebut.
Overload ini juga menggunakan boolean inclusive
. Boolean menentukan apakah
NavController
juga harus memunculkan tujuan yang ditentukan dari data sebelumnya
setelah menavigasi ke tujuan tersebut.
Perhatikan cuplikan singkat ini sebagai contoh:
navController.popBackStack(R.id.destinationId, true)
Di sini, NavController
kembali ke tujuan dengan ID bilangan bulat
destinationId
. Karena nilai argumen inclusive
adalah true
,
NavController
juga memunculkan tujuan yang ditentukan dari data sebelumnya.
Menangani pengembalian yang gagal
Saat popBackStack()
menampilkan false
, panggilan berikutnya ke
NavController.getCurrentDestination()
akan menampilkan null
. Hal ini berarti aplikasi telah
kembali ke tujuan terakhir dari data sebelumnya. Dalam hal ini, pengguna hanya melihat
layar kosong.
Hal ini dapat terjadi dalam kasus berikut:
popBackStack()
tidak memunculkan apa pun dari stack.popBackStack()
memunculkan tujuan dari data sebelumnya dan stack sekarang kosong.
Untuk mengatasi hal ini, Anda harus menavigasi ke tujuan baru atau memanggil finish()
pada aktivitas untuk mengakhirinya. Cuplikan berikut menunjukkan hal tersebut:
kotlin
...
if (!navController.popBackStack()) {
// Call finish() on your Activity
finish()
}
java
...
if (!navController.popBackStack()) {
// Call finish() on your Activity
finish();
}
Memunculkan ke tujuan
Untuk menghapus tujuan dari data sebelumnya saat menavigasi dari satu tujuan
ke tujuan lain, tambahkan argumen popUpTo()
ke panggilan fungsi navigate()
terkait. popUpTo()
menginstruksikan library Navigasi untuk menghapus beberapa tujuan
dari data sebelumnya sebagai bagian dari panggilan ke navigate()
. Nilai parameter adalah
ID tujuan di data sebelumnya. ID dapat berupa
bilangan bulat id
atau string route
.
Anda dapat menyertakan argumen untuk parameter inclusive
dengan nilai true
untuk menunjukkan bahwa tujuan yang telah Anda tentukan di popUpTo()
juga harus
muncul dari data sebelumnya.
Untuk menerapkan hal ini secara terprogram, teruskan popUpTo()
ke navigate()
sebagai bagian dari
NavOptions
dengan inclusive
ditetapkan ke true
. Tindakan ini berfungsi di Compose dan
View.
Menyimpan status saat memunculkan
Saat menggunakan popUpTo
untuk menavigasi ke tujuan, Anda dapat menyimpan
data sebelumnya dan status semua tujuan muncul dari data sebelumnya. Anda dapat
kemudian memulihkan data sebelumnya dan tujuan saat menavigasi ke tujuan tersebut
di lain waktu. Hal ini memungkinkan Anda mempertahankan status untuk tujuan tertentu dan memiliki
beberapa data sebelumnya.
Untuk melakukannya secara terprogram, tentukan saveState = true
saat menambahkan popUpTo
ke
opsi navigasi Anda.
Anda juga dapat menentukan restoreState = true
di opsi navigasi untuk
secara otomatis memulihkan data sebelumnya dan status yang terkait dengan
tujuan.
Contoh:
navController.navigate(
route = route,
navOptions = navOptions {
popUpTo<A>{ saveState = true }
restoreState = true
}
)
Untuk mengaktifkan penyimpanan dan pemulihan status dalam XML, tentukan popUpToSaveState
sebagai true
dan restoreState
sebagai true
masing-masing dalam action
terkait.
Contoh XML
Berikut adalah contoh popUpTo
di XML, menggunakan tindakan:
<action
android:id="@+id/action_a_to_b"
app:destination="@id/b"
app:popUpTo="@+id/a"
app:popUpToInclusive="true"
app:restoreState=”true”
app:popUpToSaveState="true"/>
Contoh Compose
Berikut adalah contoh lengkap yang sama di Compose:
@Composable
fun MyAppNavHost(
modifier: Modifier = Modifier,
navController: NavHostController = rememberNavController(),
startDestination: Any = A
) {
NavHost(
modifier = modifier,
navController = navController,
startDestination = startDestination
) {
composable<A> {
DestinationA(
onNavigateToB = {
// Pop everything up to, and including, the A destination off
// the back stack, saving the back stack and the state of its
// destinations.
// Then restore any previous back stack state associated with
// the B destination.
// Finally navigate to the B destination.
navController.navigate(route = B) {
popUpTo<A> {
inclusive = true
saveState = true
}
restoreState = true
}
},
)
}
composable<B> { DestinationB(/* ... */) }
}
}
@Composable
fun DestinationA(onNavigateToB: () -> Unit) {
Button(onClick = onNavigateToB) {
Text("Go to A")
}
}
Secara lebih terperinci, Anda dapat mengubah cara memanggil NavController.navigate()
dengan
cara berikut:
// Pop everything up to the destination_a destination off the back stack before
// navigating to the "destination_b" destination
navController.navigate("destination_b") {
popUpTo("destination_a")
}
// Pop everything up to and including the "destination_a" destination off
// the back stack before navigating to the "destination_b" destination
navController.navigate("destination_b") {
popUpTo("destination_a") { inclusive = true }
}
// Navigate to the "search” destination only if we’re not already on
// the "search" destination, avoiding multiple copies on the top of the
// back stack
navController.navigate("search") {
launchSingleTop = true
}
Untuk informasi umum tentang cara meneruskan opsi ke NavController.navigate()
, lihat
panduan Menavigasi dengan opsi.
Memunculkan menggunakan tindakan
Saat menavigasi menggunakan tindakan, Anda dapat memunculkan tujuan tambahan secara opsional dari data sebelumnya. Misalnya, jika aplikasi Anda memiliki alur login awal, saat pengguna login, Anda harus memunculkan semua tujuan yang terkait login dari data sebelumnya sehingga tombol Kembali tidak mengembalikan pengguna ke alur login.
Bacaan tambahan
Untuk informasi lebih lanjut, lihat halaman berikut:
- Navigasi melingkar: Pelajari cara menghindari data sebelumnya yang terlalu sesak jika alur navigasi berbentuk lingkaran.
- Tujuan dialog: Baca tentang bagaimana tujuan dialog memberikan pertimbangan unik tentang cara Anda mengelola data sebelumnya.