Jetpack Navigation'ı Navigation Compose'a taşıma

Navigation Compose API, Jetpack Navigation'ın bileşeninden, altyapısından ve özelliklerinden yararlanırken Compose uygulamasındaki composable'lar arasında gezinmenize olanak tanır.

Bu sayfada, daha büyük ve View tabanlı kullanıcı arayüzünü Jetpack Compose'a taşıma işleminin bir parçası olarak, Fragment tabanlı Jetpack Navigation'dan Navigation Compose'a nasıl geçileceği açıklanmaktadır.

Taşıma önkoşulları

Tüm parçalarınızı karşılık gelen ekran composable'larıyla değiştirebildiğinizde Navigation Compose'a geçebilirsiniz. Ekran composable'ları Compose ve View içeriklerinin bir karışımını içerebilir ancak Navigation Compose'a geçişi etkinleştirmek için tüm gezinme hedefleri composable olmalıdır. Bu tarihe kadar, birlikte çalışabilirlik için View ve Compose kod tabanınızda parça tabanlı gezinme bileşenini kullanmaya devam etmeniz gerekir. Daha fazla bilgi için navigasyon birlikte çalışabilirlik belgelerini inceleyin.

Taşıma adımları

Önerilen taşıma stratejimizi izliyor veya başka bir yaklaşım benimsiyor olsanız da tüm gezinme hedeflerinin ekran composable'ları olduğu ve Fragment'ların yalnızca composable kapsayıcılar olarak işlev gördüğü bir noktaya ulaşırsınız. Bu aşamada Navigation Compose'a geçebilirsiniz.

Uygulamanız zaten bir UDF tasarım kalıbını ve mimariyle ilgili rehberimizi kullanıyorsa Jetpack Compose ve Navigation Compose'a geçiş, kullanıcı arayüzü katmanı dışında uygulamanızın diğer katmanlarında büyük yeniden düzenlemeler gerektirmemelidir.

Navigation Compose'a geçmek için aşağıdaki adımları uygulayın:

  1. Uygulamanıza Navigation Compose bağımlılığını ekleyin.
  2. App-level composable'ı oluşturun ve Activity'nize Compose giriş noktanız olarak ekleyin. View düzeninin kurulumunu değiştirin:

    class SampleActivity : ComponentActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            // setContentView<ActivitySampleBinding>(this, R.layout.activity_sample)
            setContent {
                SampleApp(/* ... */)
            }
        }
    }

  3. Her gezinme hedefi için türler oluşturun. Veri gerektirmeyen hedefler için data object, veri gerektiren hedefler için data class veya class kullanın.

    @Serializable data object First
    @Serializable data class Second(val id: String)
    @Serializable data object Third
    

  4. NavController öğesini, referans vermesi gereken tüm composable'ların erişebileceği bir yerde ayarlayın (bu genellikle App composable'ınızın içindedir). Bu yaklaşım, durum yükseltme ilkelerine uyar ve NavController'ı, composable ekranlar arasında gezinme ve geri yığını koruma için doğruluk kaynağı olarak kullanmanıza olanak tanır:

    @Composable
    fun SampleApp() {
        val navController = rememberNavController()
        // ...
    }

  5. App composable'ın içinde uygulamanızın NavHost öğesini oluşturun ve navController öğesini iletin:

    @Composable
    fun SampleApp() {
        val navController = rememberNavController()
    
        SampleNavHost(navController = navController)
    }
    
    @Composable
    fun SampleNavHost(
        navController: NavHostController
    ) {
        NavHost(navController = navController, startDestination = First) {
            // ...
        }
    }

  6. Gezinme grafiğinizi oluşturmak için composable hedeflerini ekleyin. Her ekran daha önce Compose'a taşındıysa bu adım yalnızca bu ekran composable'larını parçalarınızdan composable hedeflerine ayırmaktan ibarettir:

    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(/* ... */)
            }
            // ...
        }
    }

  7. Compose kullanıcı arayüzünüzü tasarlama ile ilgili yönergeleri, özellikle ViewModel ve gezinme etkinliklerinin composable'lara nasıl iletilmesi gerektiği konusunda uyguladıysanız bir sonraki adım, ViewModel değerini her ekran composable'ına sağlama şeklinizi değiştirmektir. Hilt ekleme ve Compose ile Navigation'daki entegrasyon noktasını genellikle hiltViewModel aracılığıyla kullanabilirsiniz:

    @Composable
    fun FirstScreen(
        // viewModel: FirstViewModel = viewModel(),
        viewModel: FirstViewModel = hiltViewModel(),
        onButtonClick: () -> Unit = {},
    ) {
        // ...
    }

  8. Tüm findNavController() gezinme çağrılarını navController ile değiştirin ve bunları, navController'nin tamamını iletmek yerine her bir composable ekrana gezinme etkinlikleri olarak iletin. Bu yaklaşım, birleştirilebilir işlevlerden gelen etkinlikleri arayanlara göstermeyle ilgili en iyi uygulamaları izler ve navController öğesini tek bilgi kaynağı olarak tutar.

    Veriler, hedef için tanımlanan rota sınıfının bir örneği oluşturularak hedefe iletilebilir. Ardından, doğrudan hedefteki geri yığın girişinden veya ViewModel kullanılarak SavedStateHandle.toRoute() aracılığıyla elde edilebilir.

    @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)
                    }
                )
            }
            // ...
        }
    }

  9. Tüm parçaları, ilgili XML düzenlerini, gereksiz gezinmeyi ve diğer kaynakları, eski parça ve Jetpack Navigation bağımlılıklarını kaldırın.

Aynı adımları, Navigation Compose ile ilgili daha fazla ayrıntıyla birlikte kurulum belgelerinde bulabilirsiniz.

Yaygın kullanım alanları

Hangi Navigation bileşenini kullanırsanız kullanın, aynı gezinme ilkeleri geçerlidir.

Taşıma sırasında yaygın olarak kullanılan alanlar şunlardır:

Bu kullanım alanları hakkında daha ayrıntılı bilgi için Oluştur ile gezinme başlıklı makaleyi inceleyin.

Gezinirken karmaşık verileri alma

Gezinirken karmaşık veri nesnelerini aktarmamanızı önemle tavsiye ederiz. Bunun yerine, gezinme işlemleri gerçekleştirirken benzersiz bir tanımlayıcı veya başka bir kimlik biçimi gibi gerekli minimum bilgiyi bağımsız değişken olarak iletin. Karmaşık nesneleri, dataLayer gibi tek bir doğruluk kaynağında veri olarak saklamanız gerekir. Daha fazla bilgi için Gezinirken karmaşık verileri alma başlıklı makaleyi inceleyin.

Parçalarınız bağımsız değişken olarak karmaşık nesneler iletiyorsa öncelikle kodunuzu, bu nesnelerin veri katmanında depolanmasına ve veri katmanından getirilmesine olanak tanıyacak şekilde yeniden düzenlemeyi düşünün. Örnekler için Now in Android veri deposuna bakın.

Sınırlamalar

Bu bölümde, Navigation Compose ile ilgili mevcut sınırlamalar açıklanmaktadır.

Navigation Compose'a artımlı taşıma

Şu anda, kodunuzda hedef olarak Fragment'leri kullanmaya devam ederken Navigation Compose'u kullanamazsınız. Navigation Compose'u kullanmaya başlamak için tüm hedeflerinizin composable olması gerekir. Bu özellik isteğini Issue Tracker'da takip edebilirsiniz.

Geçiş animasyonları

Navigation 2.7.0-alpha01'den itibaren, daha önce AnimatedNavHost'den ayarlanan özel geçişler artık doğrudan NavHost'de desteklenmektedir. Daha fazla bilgi için sürüm notlarını okuyun.

Daha fazla bilgi

Navigation Compose'a geçiş hakkında daha fazla bilgi için aşağıdaki kaynaklara bakın:

  • Navigation Compose codelab'i: Uygulamalı bir codelab ile Navigation Compose'un temellerini öğrenin.
  • Now in Android deposu: Tamamen Kotlin ve Jetpack Compose ile oluşturulmuş, Android tasarımına ve geliştirme alanındaki en iyi uygulamalara uygun, Navigation Compose'u içeren tam işlevli bir Android uygulaması.
  • Sunflower'ı Jetpack Compose'a taşıma: Sunflower örnek uygulamasının Views'dan Compose'a taşıma sürecini belgeleyen bir blog yayınıdır. Bu yayında, Navigation Compose'a taşıma da ele alınır.
  • Her ekran için Jetnews: Jetnews örneğinin, Jetpack Compose ve Navigation Compose ile tüm ekranları destekleyecek şekilde yeniden düzenlenmesini ve taşınmasını belgeleyen bir blog yayını.