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

Navigation Compose API, Jetpack Navigation bileşeninden, altyapısından ve özelliklerinden yararlanarak bir Compose uygulamasındaki composable'lar arasında gezinmenizi sağlar.

Bu sayfada, görünüm tabanlı kullanıcı arayüzünden Jetpack Compose'a geçiş kapsamında, parça tabanlı Jetpack Navigation'dan Navigation Compose'a nasıl geçiş yapılacağı açıklanmaktadır.

Taşıma önkoşulları

Tüm Fragment'larınızı karşılık gelen ekran composable'larıyla değiştirebildiğinizde Navigation Compose'a geçebilirsiniz. Ekran composable'ları, Compose ve görünüm içeriğinin bir karışımını içerebilir ancak Navigation Compose taşıma işlemini etkinleştirmek için tüm gezinme hedeflerinin composable olması gerekir. O zamana kadar, birlikte çalışabilen View ve Compose kod tabanınızda Fragment 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 uyguluyor veya başka bir yaklaşım kullanıyor olabilirsiniz. Her iki durumda 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çiş yapabilirsiniz.

Uygulamanız zaten bir UDF tasarım kalıbına ve mimari kılavuzumuza uyuyorsa Jetpack Compose ve Navigation Compose'a geçiş için uygulamanızın kullanıcı arayüzü katmanı dışındaki diğer katmanlarında büyük yeniden düzenlemeler yapmanız gerekmez.

Navigation Compose'a geçiş yapmak 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 bunu Compose giriş noktanız olarak Activity'nize ekleyerek görünüm 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'i, 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, state hoisting ilkelerine uygundur ve composable ekranlar arasında gezinmek ve eski yığını korumak için NavController öğesini doğruluk kaynağı olarak kullanmanıza olanak tanır:

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

  5. App composable'ını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 hedefi ekleyin. Her ekran daha önce Compose'a taşındıysa bu adım yalnızca bu ekran composable'larını Fragment'larınızdan composable hedeflerine ayıklamaktan 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 kılavuzda yer alan talimatları, özellikle de ViewModel ve gezinme etkinliklerinin composable'lara nasıl aktarılması gerektiğini uyguladıysanız bir sonraki adım, her ekran composable'ına ViewModel sağlama şeklinizi değiştirmektir. Hilt ekleme ve bunun Compose ve Navigation ile entegrasyon noktasını 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 çağrılarıyla değiştirin ve tüm navController yerine bunları her bir composable ekrana gezinme etkinlikleri olarak iletin. Bu yaklaşım, composable işlevlerdeki etkinlikleri arayanlara göstermeyle ilgili en iyi uygulamaları takip eder ve navController öğesini tek doğruluk 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 eski yığın girişinden veya SavedStateHandle.toRoute() kullanarak bir ViewModel öğesinden alınabilir.

    @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 Fragment'ları, ilgili XML düzenlerini, gereksiz gezinme ve diğer kaynakları, eski Fragment ve Jetpack Navigation bağımlılıklarını kaldırın.

Aynı adımları ve Navigation Compose ile ilgili daha fazla ayrıntıyı Kurulum belgelerinde bulabilirsiniz.

Yaygın kullanım alanları

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

Taşıma işlemi sırasında yaygın kullanım alanları şunlardır:

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

Navigasyon sırasında karmaşık verileri alma

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

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

Sınırlamalar

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

Navigation Compose'a aşamalı geçiş

Şu anda, kodunuzda hedef olarak parçaları 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 sürümünden itibaren, daha önce AnimatedNavHost tarafından sağlanan özel geçişleri ayarlama desteği artık doğrudan NavHost tarafından sağlanmaktadır. 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 göz atın:

  • Navigation Compose codelab'i: Uygulamalı bir codelab ile Navigation Compose'un temel bilgilerini öğrenin.
  • Now in Android deposu: Tamamen Kotlin ve Jetpack Compose ile oluşturulmuş, Android tasarım ve geliştirme en iyi uygulamalarını takip eden ve Navigation Compose'u içeren, tam işlevli bir Android uygulaması.
  • Sunflower'ı Jetpack Compose'a taşıma: Sunflower örnek uygulamasının View'lardan Compose'a geçiş yolculuğunu belgeleyen bir blog yayını. Bu yayında, Navigation Compose'a geçiş de ele alınmaktadı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ı.