Geçiş, kullanıcıların uygulamanızda gezinme şeklini açıklar. Kullanıcılar, genellikle dokunarak veya tıklayarak kullanıcı arayüzü öğeleriyle etkileşim kurar ve uygulama, yeni içerik göstererek yanıt verir. Kullanıcı önceki içeriğe dönmek istiyorsa geri hareketini kullanır veya geri düğmesine dokunur.
Gezinme durumunu modelleme
Bu davranışı modellemenin uygun bir yolu, içerik yığını kullanmaktır. Kullanıcı yeni içeriğe ilerledikçe bu içerik yığının en üstüne gönderilir. İzleyiciler bu içerikten geri döndüğünde içerik yığından çıkarılır ve önceki içerik gösterilir. Bu yığın, gezinme açısından genellikle geri yığını olarak adlandırılır. Bunun nedeni, kullanıcının geri gidebileceği içeriği temsil etmesidir.
Geri yığın oluşturma
Navigation 3'te geri yığında aslında içerik bulunmaz. Bunun yerine, anahtarlar olarak bilinen içerik referansları bulunur. Anahtarlar herhangi bir türde olabilir ancak genellikle basit, serileştirilebilir veri sınıflarıdır. İçerik yerine referans kullanmanın aşağıdaki avantajları vardır:
- Tuşları geri yığına göndererek gezinmek kolaydır.
- Anahtarlar serileştirilebilir olduğu sürece eski yığın kalıcı depolama alanına kaydedilebilir. Bu sayede, yapılandırma değişikliklerinden ve işlem sonlandırmadan etkilenmez. Kullanıcılar uygulamanızdan ayrılmayı, daha sonra geri dönmeyi ve aynı içerik gösterilirken kaldıkları yerden devam etmeyi beklediğinden bu önemlidir. Daha fazla bilgi için Arka taraftaki kartlarınızı kaydetme başlıklı makaleyi inceleyin.
Navigation 3 API'deki temel kavramlardan biri, geri yığınına sahip olmanızdır. Kitaplık:
- Geri yığınınızın, anlık görüntü durumu destekli bir
List<T>olmasını bekler. BuradaT, geri yığınınızın türükeys'dir.Anykullanabilir veya kendi daha güçlü türde anahtarlarınızı sağlayabilirsiniz. "Push" veya "pop" terimlerini gördüğünüzde, temel uygulama, öğeleri listenin sonuna eklemek veya listeden kaldırmaktır. - Geri yığını gözlemler ve durumunu
NavDisplaykullanarak kullanıcı arayüzüne yansıtır.
Aşağıdaki örnekte, anahtarların ve geri yığınının nasıl oluşturulacağı ve geri yığınının kullanıcı gezinme etkinliklerine yanıt olarak nasıl değiştirileceği gösterilmektedir:
// Define keys that will identify content data object ProductList data class ProductDetail(val id: String) @Composable fun MyApp() { // Create a back stack, specifying the key the app should start with val backStack = remember { mutableStateListOf<Any>(ProductList) } // Supply your back stack to a NavDisplay so it can reflect changes in the UI // ...more on this below... // Push a key onto the back stack (navigate forward), the navigation library will reflect the change in state backStack.add(ProductDetail(id = "ABC")) // Pop a key off the back stack (navigate back), the navigation library will reflect the change in state backStack.removeLastOrNull() }
İçerik anahtarlarını çözme
İçerik, Navigation 3'te composable işlev içeren bir sınıf olan NavEntry kullanılarak modellenir. Bu, kullanıcının ileri ve geri gidebileceği tek bir içerik olan hedefi temsil eder.
NavEntry, içerikle ilgili bilgiler olan meta verileri de içerebilir. Bu meta veriler, NavDisplay gibi kapsayıcı nesneler tarafından okunarak NavEntry içeriğinin nasıl görüntüleneceğine karar vermelerine yardımcı olabilir. Örneğin, meta veriler belirli bir NavEntry için varsayılan animasyonları geçersiz kılmak üzere kullanılabilir. NavEntry
metadata, çok yönlü veri depolama sağlayan String anahtarlarının Any değerleriyle eşlendiği bir haritadır.
key birimini NavEntry birimine dönüştürmek için Giriş Sağlayıcı oluşturun. Bu, key değerini kabul eden ve bu key için NavEntry değerini döndüren bir fonksiyondur. Genellikle NavDisplay oluşturulurken lambda parametresi olarak tanımlanır.
Giriş sağlayıcı oluşturmanın iki yolu vardır: doğrudan bir lambda işlevi oluşturmak veya entryProvider DSL'yi kullanmak.
Doğrudan giriş sağlayıcı işlevi oluşturma
Genellikle her bir anahtarınız için bir dal içeren bir when ifadesi kullanarak bir Giriş Sağlayıcı işlevi oluşturursunuz.
entryProvider = { key -> when (key) { is ProductList -> NavEntry(key) { Text("Product List") } is ProductDetail -> NavEntry( key, metadata = mapOf("extraDataKey" to "extraDataValue") ) { Text("Product ${key.id} ") } else -> { NavEntry(Unit) { Text(text = "Invalid Key: $it") } } } }
entryProvider DSL'sini kullanma
entryProvider DSL, her bir anahtar türünüze karşı test yapma ve her biri için NavEntry oluşturma ihtiyacını ortadan kaldırarak lambda işlevinizi basitleştirebilir.
Bunun için entryProvider oluşturma işlevini kullanın. Anahtar bulunamazsa varsayılan geri dönüş davranışı (hata oluşturma) da içerir.
entryProvider = entryProvider { entry<ProductList> { Text("Product List") } entry<ProductDetail>( metadata = mapOf("extraDataKey" to "extraDataValue") ) { key -> Text("Product ${key.id} ") } }
Snippet'ten aşağıdaki bilgileri not edin:
entry, belirli bir tür ve birleştirilebilir içerik ileNavEntrytanımlamak için kullanılır.entry,NavEntry.metadatadeğerini ayarlamak içinmetadataparametresini kabul eder.
Geri yığınını görüntüleme
Geri yığını, uygulamanızın gezinme durumunu temsil eder. Eski yığın her değiştiğinde uygulama kullanıcı arayüzü, yeni eski yığın durumunu yansıtmalıdır. Navigation 3'te bir NavDisplay, eski yığınınızı izler ve kullanıcı arayüzünü buna göre günceller. Aşağıdaki parametrelerle oluşturun:
- Geriye dönme yığınınız: Bu,
SnapshotStateList<T>türünde olmalıdır. BuradaT, geriye dönme yığını anahtarlarınızın türüdür. Bu, gözlemlenebilir birListolduğundan değiştiğindeNavDisplay'nin yeniden oluşturulmasını tetikler. - Geri yığınınızdaki anahtarları
NavEntrynesnelere dönüştürmek içinentryProvider. - İsteğe bağlı olarak,
onBackparametresine bir lambda sağlayın. Bu, kullanıcı bir geri etkinliğini tetiklediğinde çağrılır.
Aşağıdaki örnekte NavDisplay nasıl oluşturulacağı gösterilmektedir.
data object Home data class Product(val id: String) @Composable fun NavExample() { val backStack = remember { mutableStateListOf<Any>(Home) } NavDisplay( backStack = backStack, onBack = { backStack.removeLastOrNull() }, entryProvider = { key -> when (key) { is Home -> NavEntry(key) { ContentGreen("Welcome to Nav3") { Button(onClick = { backStack.add(Product("123")) }) { Text("Click to navigate") } } } is Product -> NavEntry(key) { ContentBlue("Product ${key.id} ") } else -> NavEntry(Unit) { Text("Unknown route") } } } ) }
Varsayılan olarak, NavDisplay, tek bölmeli düzende eski yığındaki en üstteki NavEntry öğesini gösterir. Aşağıdaki kayıtta bu uygulamanın çalıştığı gösterilmektedir:
NavDisplay hedefli varsayılan davranış.Hedef yaşam döngüsü
NavDisplay, hem sahne düzeyindeki kısıtlamalara hem de giriş düzeyindeki kısıtlamalara göre bir NavEntry öğesinin yaşam döngüsü durumunu sınırlamak için özel LifecycleOwners kullanır.
Compose'daki yaşam döngüleri hakkında daha fazla bilgi için Jetpack Compose'da Yaşam Döngüsü başlıklı makaleyi inceleyin.
Sahne düzeyinde yaşam döngüsü kısıtlamaları
NavDisplay, etkin Scene'lerin yaşam döngüsünü yönetir. Sahne düzeyindeki sınırlar aşağıdaki şekilde belirlenir:
Yer paylaşımı olmayan sahneler için:
RESUMED: Yalnızca sahne geçişi tamamlandığında ve üzerinde etkin yer paylaşımı sahneleri gösterilmediğinde izin verilir.STARTED: Sahne geçişleri sırasında (ör. ileri veya geri giderken ya da bir yer paylaşımı tarafından kapatıldığında)STARTEDile sınırlanır.
İletişim kutuları veya alt sayfalar gibi yer paylaşımlı sahneler için:
RESUMED: Yalnızca en üstteki, etkin durumda olan yer paylaşımı sahnesi için izin verilir.STARTED: Daha yeni bir yer paylaşımıyla kapsanan temel yer paylaşımı sahneleri içinSTARTEDile sınırlıdır.
Başlangıç düzeyi yaşam döngüsü durumu
Kitaplık, her bir NavEntry öğesinin maksimum yaşam döngüsü durumunu, geri yığında bulunmasına göre yönetir:
RESUMED: Giriş mevcut geri yığında bulunuyorsa yaşam döngüsününRESUMED'e kadar çıkmasına izin verilir (sahne düzeyindeki sınıra tabidir).CREATED: Giriş artık geri yığında değilse (ör. giriş çıkarılmış ancak animasyonla ekrandan kaldırılırken ekranda oluşturulmaya devam ediyorsa) kitaplık, yaşam döngüsünü kesinlikleCREATEDile sınırlar. Bu sınır, arka plandaki veya çıkış yapan girişlerin, çıkış geçişlerini tamamlarken akış toplama ya daRESUMEDveyaSTARTEDdurumlarına bağlı eşzamanlı rutinleri başlatma gibi etkin işleri yürütmeyi durdurmasını sağlar.
Birleştirme şekli
Örneğin, bir NavEntry öğesinin nihai yaşam döngüsü durumu aşağıdaki şekilde belirlenir:
| Senaryo | Sahne Düzeyinde Sınır | Başlangıç Düzeyi Sınırı | Etkin Sınır |
|---|---|---|---|
| Etkin giriş, yerleşmiş ekran (geçiş veya yer paylaşımı yok) | RESUMED |
RESUMED |
RESUMED |
| Geçiş sırasında etkin giriş (bir yere giderken veya bir yerden gelirken) | STARTED |
RESUMED |
STARTED |
| Etkin giriş, yer paylaşımıyla kaplı (örneğin, bir iletişim kutusu açık) | STARTED |
RESUMED |
STARTED |
| Animasyonla çıkan giriş | STARTED veya RESUMED |
CREATED |
CREATED |
Özet
Aşağıdaki diyagramda, Navigation 3'teki çeşitli nesneler arasında veri akışının nasıl gerçekleştiği gösterilmektedir:
Geçiş etkinlikleri değişiklikleri başlatır. Anahtarlar, kullanıcı etkileşimlerine yanıt olarak geri yığına eklenir veya geri yığından kaldırılır.
Geri yığın durumundaki değişiklik, içerik alımını tetikler.
NavDisplay(eski yığın oluşturan bir composable) eski yığını gözlemler. Varsayılan yapılandırmasında, en üstteki geri yığın girişini tek bölmeli bir düzende gösterir. Arka yığındaki en üstteki anahtar değiştiğindeNavDisplay, giriş sağlayıcıdan ilgili içeriği istemek için bu anahtarı kullanır.Giriş sağlayıcı içerik sunar. Giriş sağlayıcı, bir anahtarı
NavEntryile eşleyen bir işlevdir.NavDisplayanahtarı aldıktan sonra giriş sağlayıcı, hem anahtarı hem de içeriği içeren ilişkiliNavEntrysağlar.İçerik gösterilir.
NavDisplay,NavEntryöğesini alır ve içeriği gösterir.