Arsitektur Navigasi Jetpack Compose
Mari kita telusuri Komponen Navigasi di Compose dengan kode contoh dan tulis Tes UI untuk Komponen Navigasi.
Navigasi di Compose memiliki bagian kunci yang sama dengan Navigasi dasar Tampilan tradisional, mari kita lihat deskripsi dasar dan akan membahas detail lebih jauh ke bawah
- Grafik Navigasi: Ini menentukan tujuan yang dapat disusun yang dapat dinavigasi oleh pengguna, setiap tujuan yang dapat disusun dikaitkan dengan route , route adalah kunci unik yang menentukan setiap tujuan yang dapat disusun.
- NavHost: Ini adalah komposisi yang menentukan semua kemungkinan tujuan yang dapat disusun di dalam menggunakan kata kunci yang dapat disusun . Saat pengguna bernavigasi di antara berbagai tujuan yang dapat disusun, konten NavHost dikomposisi ulang untuk menampilkan komposisi yang sesuai.
- NavigationController: Ini mengelola semua navigasi di dalam NavHost , Ini menavigasi ke masing-masing tujuan dan menampilkan layar yang dapat disusun yang sesuai. Ini stateful dan melacak tumpukan kompos yang digunakan dalam navigasi dan negara bagian
Apa itu rute?
route adalah kunci yang digunakan untuk menentukan setiap tujuan yang dapat disusun tempat Anda dapat menavigasi menggunakan navController , Anda dapat menganggapnya sebagai tautan dalam ke yang dapat disusun. Ini harus secara unik mengidentifikasi setiap tujuan yang dapat disusun
mari kita ke contoh kode.
Contoh
Sebagai contoh, kami akan menggunakan contoh proyek aplikasi musik yang memiliki tiga layar, Layar Lagu, Layar Favorit, dan Layar Pencarian.
Untuk menunjukkan penggunaan navigasi, kami akan membuatnya tetap sederhana dan akan membuat layar Beranda yang memiliki tiga tombol untuk menavigasi ke masing-masing layar yang disebutkan di atas.
HomeScreen dibuat untuk menampilkan navigasi, Dalam proyek nyata Anda akan menggunakan navigasi bawah atau navigasi laci berdasarkan kebutuhan Anda
Ketergantungan
implementation "androidx.navigation:navigation-compose:2.5.3"
NavHost adalah fungsi yang dapat disusun yang menggunakan NavigationController yang dibuat dari mengingatNavController() api dan rute tujuan awal sebagai parameter. NavHost memperlihatkan lambda yang kami gunakan untuk menyediakan semua kemungkinan tujuan menggunakan kata kunci yang dapat disusun
Dalam contoh kami, kami akan membuat NavHost dengan empat tujuan penulisan menggunakan kata kunci yang dapat disusun, menentukan setiap rute tujuan dan komponen yang akan dinavigasi. Kami akan meneruskan startDestination di NavHost sebagai rute "beranda" , HomeScreen yang dapat disusun akan muncul sebagai layar pertama
@Composable
fun MainNavigation(
navController: NavHostController = rememberNavController()
) {
NavHost(
navController = navController,
startDestination = "home"
) {
composable("home") { HomeScreen() }
composable("songs") { SongsScreen() }
composable("favourites") { FavouritesScreen() }
composable("search") { SearchScreen()}
}
}
setContent {
ComposeNavigationTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
MainNavigation()
}
}
}
NavHost bertindak sebagai wadah yang saat ini menampilkan HomeScreen sebagai "rumah" ditetapkan sebagai tujuan Mulai untuk NavHost
Bagaimana Cara Menavigasi?
Untuk menavigasi ke tujuan yang dapat disusun di Navigation Grpah, Anda akan menggunakan metode navigasi di navController dan meneruskan rute tujuan yang ingin Anda navigasikan
navController.navigate("songs")
Dalam contoh kami, HomeScreen yang dapat dikomposisi akan mengarah ke SongsScreen , FavouritesScreen , dan SearchScreen yang dapat dikomposisi.
Bagaimana cara menavigasi dari dalam yang dapat disusun?
Untuk mematuhi satu sumber kebenaran dan mempertahankan status hoisting , hanya fungsi yang dapat dikompilasi yang mengangkat NavController atau fungsi yang dapat disusun yang menggunakan NavController yang harus melakukan navigasi. Kita harus menghindari melakukan navigasi dalam komposisi yang lebih rendah dalam hierarki karena hal itu akan menyebabkan penyambungan, kode tidak akan dapat diskalakan di masa mendatang.
Bagaimana cara mencapai ini? Anda dapat mencapainya dengan mengekspos fungsi Lambda daripada meneruskan navController sebagai parameter ke bawah dalam hierarki. Lihat di bawah…
Dalam contoh kami, kami ingin navigasi dari HomeScreen yang dapat disusun ke tiga komposisi lainnya, jadi kami akan mengekspos tiga metode lambda dari HomeScreen yang dapat disusun diNavigateToSongs, onNavigateToFavourites, onNavigateToSearch dan pada setiap penekanan tombol, kami akan memanggil lambda yang sesuai ini yang pada akhirnya akan menavigasi ke tujuan tertentu yang dapat disusun tersebut , Lihat kode di bawah ini.
lihat perubahan pada komposisi HomeScreen seperti yang dijelaskan di atas
@Composable
fun HomeScreen(
onNavigateToSongs: () -> Unit,
onNavigateToFavourites: () -> Unit,
onNavigateToSearch: () -> Unit
) {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Button( onClick = { onNavigateToSongs() }) {
Text(text = "Go to Songs")
}
Spacer(modifier = Modifier.size(8.dp))
Button(onClick = { onNavigateToFavourites() }) {
Text(text = "Go to Favourites")
}
Spacer(modifier = Modifier.size(8.dp))
Button(onClick = { onNavigateToSearch() }) {
Text(text = "Search Song")
}
}
}
@Composable
fun MainNavigation(
navController: NavHostController = rememberNavController()
) {
NavHost(
navController = navController,
startDestination = "home"
) {
composable("home") { HomeScreen(
onNavigateToSongs = { navController.navigate("songs") },
onNavigateToFavourites = { navController.navigate("favourites") },
onNavigateToSearch = {navController.navigate("search") }
) }
composable("songs") { SongsScreen() }
composable("favourites") { FavouritesScreen() }
composable("search") { SearchScreen()}
}
}
Jalankan aplikasi, Anda akan melihat navigasi berfungsi dan tombol kembali perangkat juga akan berfungsi secara otomatis. Menekan tombol kembali perangkat akan memunculkan komposisi atas kembali pada tumpukan belakang yang dikelola secara internal oleh NavController .
Bagaimana cara menavigasi dari hierarki tingkat berikutnya?
Katakanlah kita ingin menavigasi dari SearchScreen yang dapat disusun kembali ke SongsScreen , jadi mari tambahkan tombol di SearchScreen dan tampilkan fungsi lambda yang akan dipanggil pada tombol yang diklik dan navigasi ke SongsScreen akan terjadi pada tingkat yang lebih tinggi di dalam MainNavigation yang dapat disusun.
Mari kita lihat melalui contoh kode, pertama lihat bagaimana tampilan SearchScreen baru yang dapat disusun
@Composable
fun SearchScreen(
onNavigateToSongs: () -> Unit,
) {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "Search Screen")
Spacer(modifier = Modifier.size(8.dp))
Button(onClick = onNavigateToSongs) {
Text(text = "Go to Songs")
}
}
}
@Composable
fun MainNavigation(
navController: NavHostController = rememberNavController()
) {
NavHost(
navController = navController,
startDestination = "home"
) {
composable("home") { HomeScreen(
onNavigateToSongs = { navController.navigate("songs") },
onNavigateToFavourites = { navController.navigate("favourites") },
onNavigateToSearch = { navController.navigate("search") }
) }
composable("songs") { SongsScreen() }
composable("favourites") { FavouritesScreen() }
composable("search") { SearchScreen(
onNavigateToSongs = { navController.navigate("songs") }
) }
}
}
TAPI ada satu masalah! Setelah Anda menavigasi ke SongsScreen dari SearchScreen dan menekan tombol kembali perangkat, Anda akan melihat SearchScreen lagi, Biasanya dan di sebagian besar kasus penggunaan, kami tidak ingin layar perantara ini muncul lagi, melainkan kembali ke HomeScreen
Bagaimana cara mencapai ini? Anda dapat mencapai ini dengan menerapkan fungsi lambda pada metode navigasi navController dan memunculkan semuanya ke tujuan rumah dari tumpukan belakang sebelum menavigasi ke SongsSceen , lihat kode di bawah ini.
composable("search") { SearchScreen(
onNavigateToSongs = { navController.navigate("songs") {
// pop up everything to the "home" destination before navigating
// to "songs" destination
popUpTo("home")
}}
)}
@Composable
fun MainNavigation(
navController: NavHostController = rememberNavController()
) {
NavHost(
navController = navController,
startDestination = "home"
) {
composable("home") { HomeScreen(
onNavigateToSongs = { navController.navigate("songs") },
onNavigateToFavourites = { navController.navigate("favourites") },
onNavigateToSearch = { navController.navigate("search") }
)}
composable("songs") { SongsScreen() }
composable("favourites") { FavouritesScreen() }
composable("search") { SearchScreen(
onNavigateToSongs = { navController.navigate("songs") {
// pop up everything to the "home" destination before navigating
// to "songs" destination
popUpTo("home")
}}
)}
}
}
Ada beberapa kasus penggunaan umum dalam navigasi, mari kita lihat cara mencapainya
Gunakan-kasus di mana Anda ingin rute popUpTo termasuk rute itu: Untuk mencapai ini, Anda harus menerapkan fungsi lambda lebih lanjut dari metode popUpTo yang menentukan{ inclusive = true }
navController.navigate("navigateToRoot") {
// pop up everything including "popupRoot" destination before navigating
// to "navigateToRoot" destination
popUpTo("popupRoot") { inclusive = true }
}
Bagaimana cara menghindarinya? Anda harus menentukan launchSingleTop = truedalam fungsi lambda metode navigasi, lihat contoh kode di bawah ini
navController.navigate("songs") {
launchSingleTop = true
}
Untuk meringkas lagi praktik terbaik untuk Navigasi.
Pertahankan logika navigasi Anda dalam hierarki yang mengekspos fungsi lambda untuk komposisi yang ingin menavigasi ke komposisi lainnya. Itu mungkin membebani tanda tangan fungsi yang dapat disusun tetapi memiliki manfaat seperti yang dijelaskan di bawah ini
- Mengekspos peristiwa dari composable ke penelepon memanfaatkan konsep pengangkatan status , menjaga agar composable yang lebih rendah tidak memiliki kewarganegaraan
- Akan memberikan visibilitas pada tingkat yang lebih tinggi tentang cara kerja logika navigasi sebagai satu-satunya sumber kebenaran
- Memaksimalkan visibilitas setiap fungsi yang dapat disusun, tanggung jawab apa yang dimiliki suatu komposisi, memungkinkan untuk melihat apa yang dilakukannya secara sekilas
- Testabilitas: Hal ini memungkinkan composable Anda dapat diuji satu per satu karena Anda tidak perlu meneruskan Pengontrol Nav dalam parameter, dan lambda yang diteruskan untuk navigasi dapat disetel kosong {} saat menulis pengujian
Ada masalah bahwa string kunci rute digunakan di banyak tempat, salah satunya dalam menentukan komposisi tujuan di NavHost dan lainnya saat menavigasi ke tujuan tertentu, itu tidak baik karena string kunci yang sama digunakan di banyak tempat dan jika Anda harus mengubahnya, Anda perlu melakukannya ubah di mana pun yang ditentukan dan semakin sulit dan dapat menimbulkan masalah saat kode bertambah besar
Untuk meningkatkan ini, mari buat kelas tersegel di atas mengambil rute sebagai kunci string yang melacak semua kunci rute rute kami
sealed class Screen(val route: String) {
object Home: Screen("home")
object Songs: Screen("songs")
object Favourites: Screen("favourites")
object Search: Screen("search")
}
@Composable
fun MainNavigation(
navController: NavHostController = rememberNavController()
) {
NavHost(
navController = navController,
startDestination = Screen.Home.route
) {
composable(Screen.Home.route) { HomeScreen(
onNavigateToSongs = { navController.navigate(Screen.Songs.route) {
launchSingleTop = true
} },
onNavigateToFavourites = { navController.navigate(Screen.Favourites.route) },
onNavigateToSearch = { navController.navigate(Screen.Search.route) }
)}
composable(Screen.Songs.route) { SongsScreen() }
composable(Screen.Favourites.route) { FavouritesScreen() }
composable(Screen.Search.route) { SearchScreen(
onNavigateToSongs = { navController.navigate(Screen.Songs.route) {
// pop up everything to the "home" destination before navigating
// to "songs" destination
popUpTo(Screen.Home.route)
}}
)}
}
Menguji Navigasi UI
Saya telah menulis cerita lain tentang pengujian komponen navigasi yang memperluas contoh yang sama di sini
Repo ada di sini

![Apa itu Linked List? [Bagian 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































