Navigation Compose API memungkinkan Anda bernavigasi antar-composable di aplikasi Compose, sekaligus memanfaatkan komponen, infrastruktur, dan fitur Jetpack Navigation.
Halaman ini menjelaskan cara bermigrasi dari Navigasi Jetpack berbasis Fragment ke Navigation Compose, sebagai bagian dari migrasi UI berbasis View yang lebih besar ke Jetpack Compose.
Prasyarat migrasi
Anda dapat bermigrasi ke Navigation Compose setelah dapat mengganti semua Fragment dengan composable layar yang sesuai. Composable layar dapat berisi campuran konten Compose dan View, tetapi semua tujuan navigasi harus berupa composable untuk mengaktifkan migrasi Navigation Compose. Sebelum itu, Anda harus terus menggunakan komponen Navigasi berbasis Fragment di kode View dan Compose interop Anda. Lihat dokumentasi interoperabilitas navigasi untuk mengetahui informasi selengkapnya.
Penggunaan Navigation Compose di aplikasi khusus Compose bukanlah prasyarat. Anda dapat terus menggunakan Komponen Navigasi berbasis Fragmen, selama Anda tetap menggunakan Fragmen untuk menampung konten yang dapat dikomposisi.
Langkah migrasi
Baik Anda mengikuti strategi migrasi yang direkomendasikan atau mengambil pendekatan lain, Anda akan mencapai titik di mana semua tujuan navigasi adalah composable layar, dengan Fragment hanya bertindak sebagai penampung composable. Pada tahap ini, Anda dapat bermigrasi ke Navigation Compose.
Jika aplikasi Anda sudah mengikuti pola desain UDF dan panduan arsitektur kami, migrasi ke Jetpack Compose dan Navigation Compose tidak memerlukan refaktor besar pada lapisan lain aplikasi Anda, selain lapisan UI.
Untuk bermigrasi ke Navigation Compose, ikuti langkah-langkah berikut:
- Tambahkan dependensi Navigation Compose ke aplikasi Anda.
Buat composable
App-level
dan tambahkan keActivity
sebagai titik entri Compose, menggantikan penyiapan tata letak View:class SampleActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // setContentView<ActivitySampleBinding>(this, R.layout.activity_sample) setContent { SampleApp(/* ... */) } } }
Buat jenis untuk setiap tujuan navigasi. Gunakan
data object
untuk tujuan yang tidak memerlukan data dandata class
atauclass
untuk tujuan yang memerlukan data.@Serializable data object First @Serializable data class Second(val id: String) @Serializable data object Third
Siapkan
NavController
di tempat yang dapat diakses oleh semua composable yang perlu mereferensikannya (biasanya di dalam composableApp
). Pendekatan ini mengikuti prinsip penarikan status dan memungkinkan Anda menggunakanNavController
sebagai sumber kebenaran untuk menavigasi di antara layar composable dan mempertahankan data sebelumnya:@Composable fun SampleApp() { val navController = rememberNavController() // ... }
Buat
NavHost
aplikasi Anda di dalam composableApp
dan teruskannavController
:@Composable fun SampleApp() { val navController = rememberNavController() SampleNavHost(navController = navController) } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { // ... } }
Tambahkan tujuan
composable
untuk membuat grafik navigasi Anda. Jika setiap layar telah dimigrasikan ke Compose sebelumnya, langkah ini hanya terdiri dari mengekstraksi composable layar ini dari Fragment Anda ke tujuancomposable
:class FirstFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { return ComposeView(requireContext()).apply { setContent { // FirstScreen(...) EXTRACT FROM HERE } } } } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { composable<First> { FirstScreen(/* ... */) // EXTRACT TO HERE } composable<Second> { SecondScreen(/* ... */) } // ... } }
Jika Anda mengikuti panduan tentang membangun arsitektur UI Compose, khususnya cara meneruskan
ViewModel
dan peristiwa navigasi ke composable, langkah berikutnya adalah mengubah cara Anda memberikanViewModel
ke setiap composable layar. Anda sering kali dapat menggunakan injeksi Hilt dan titik integrasinya dengan Compose dan Navigation melaluihiltViewModel
:@Composable fun FirstScreen( // viewModel: FirstViewModel = viewModel(), viewModel: FirstViewModel = hiltViewModel(), onButtonClick: () -> Unit = {}, ) { // ... }
Ganti semua panggilan navigasi
findNavController()
dengan panggilannavController
dan teruskan panggilan ini sebagai peristiwa navigasi ke setiap layar composable, bukan meneruskan seluruhnavController
. Pendekatan ini mengikuti praktik terbaik dalam mengekspos peristiwa dari fungsi composable ke pemanggil dan mempertahankannavController
sebagai satu sumber tepercaya.Data dapat diteruskan ke tujuan dengan membuat instance class rute yang ditentukan untuk tujuan tersebut. Kemudian,
ViewModel
dapat diperoleh secara langsung dari entri data sebelumnya di tujuan atau dariViewModel
menggunakanSavedStateHandle.toRoute()
.@Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { composable<First> { FirstScreen( onButtonClick = { // findNavController().navigate(firstScreenToSecondScreenAction) navController.navigate(Second(id = "ABC")) } ) } composable<Second> { backStackEntry -> val secondRoute = backStackEntry.toRoute<Second>() SecondScreen( id = secondRoute.id, onIconClick = { // findNavController().navigate(secondScreenToThirdScreenAction) navController.navigate(Third) } ) } // ... } }
Hapus semua Fragment, tata letak XML yang relevan, navigasi yang tidak diperlukan, dan resource lainnya, serta dependensi Jetpack Navigation dan Fragment yang sudah tidak berlaku.
Anda dapat menemukan langkah-langkah yang sama dengan detail terkait Navigation Compose lainnya di Dokumentasi penyiapan.
Kasus penggunaan umum
Apa pun komponen Navigation yang Anda gunakan, prinsip navigasi yang sama berlaku.
Kasus penggunaan umum saat melakukan migrasi meliputi:
- Menavigasi ke composable
- Menavigasi dengan argumen
- Deep link
- Navigasi bertingkat
- Integrasi dengan menu navigasi bawah
- Integrasi dengan komponen nav kustom
Untuk mengetahui informasi yang lebih mendetail tentang kasus penggunaan ini, lihat Menavigasi dengan Compose.
Mengambil data kompleks saat menavigasi
Sebaiknya jangan meneruskan objek data yang kompleks saat menavigasi. Sebagai gantinya, teruskan informasi minimum yang diperlukan, seperti ID unik atau bentuk ID lainnya, sebagai argumen saat melakukan tindakan navigasi. Anda harus menyimpan objek kompleks sebagai data dalam satu sumber tepercaya, seperti lapisan data. Untuk mengetahui informasi selengkapnya, lihat Mengambil data kompleks saat menavigasi.
Jika Fragmen Anda meneruskan objek kompleks sebagai argumen, pertimbangkan untuk memfaktorkan ulang kode Anda terlebih dahulu, dengan cara yang memungkinkan penyimpanan dan pengambilan objek ini dari lapisan data. Lihat repositori Now in Android untuk melihat contohnya.
Batasan
Bagian ini menjelaskan batasan saat ini untuk Navigation Compose.
Migrasi inkremental ke Navigation Compose
Saat ini, Anda tidak dapat menggunakan Navigation Compose sambil tetap menggunakan Fragmen sebagai tujuan dalam kode Anda. Untuk mulai menggunakan Navigation Compose, semua tujuan Anda harus berupa composable. Anda dapat memantau permintaan fitur ini di Issue Tracker.
Animasi transisi
Mulai dari Navigation 2.7.0-alpha01, dukungan untuk menyetel transisi kustom, sebelumnya dari AnimatedNavHost
, kini
didukung langsung di NavHost
. Baca catatan rilis untuk mengetahui informasi selengkapnya.
Pelajari lebih lanjut
Untuk mengetahui informasi selengkapnya tentang migrasi ke Navigation Compose, lihat referensi berikut:
- Codelab Navigation Compose: Pelajari dasar-dasar Navigation Compose dengan codelab praktis.
- Repositori Now in Android: Aplikasi Android yang berfungsi penuh dan sepenuhnya dibangun dengan Kotlin dan Jetpack Compose, yang mengikuti praktik terbaik desain dan pengembangan Android serta menyertakan Navigation Compose.
- Memigrasikan Sunflower ke Jetpack Compose: Postingan blog yang mendokumentasikan perjalanan migrasi aplikasi contoh Sunflower dari View ke Compose, yang juga mencakup migrasi ke Navigation Compose.
- Jetnews untuk semua layar: Postingan blog yang mendokumentasikan pemfaktoran ulang dan migrasi contoh Jetnews untuk mendukung semua layar dengan Jetpack Compose dan Navigation Compose.
Direkomendasikan untuk Anda
- Catatan: teks link ditampilkan saat JavaScript nonaktif
- Menavigasi dengan Compose
- Compose dan library lainnya
- Pertimbangan lainnya