Gezinme, kullanıcıların uygulamanızda nasıl hareket ettiğini açıklar. Kullanıcılar, genellikle kullanıcı arayüzü öğelerine dokunarak veya tıklayarak bu öğelerle etkileşim kurar ve uygulama, yeni içerik göstererek yanıt verir. Kullanıcı önceki içeriğe dönmek isterse geri hareketini kullanır veya geri düğmesine dokunur.
Gezinme durumunu modelleme
Bu davranışı modellemenin kolay bir yolu, içerik yığını kullanmaktır. Kullanıcı yeni içeriğe ileri doğru gittiğinde bu içerik yığının en üstüne eklenir. Kullanıcı bu içerikten geri gittiğinde içerik yığından çıkarılır ve önceki içerik gösterilir. Gezinme terimleriyle ifade etmek gerekirse bu yığın, kullanıcının geri dönebileceği içeriği temsil ettiği için genellikle eski yığın olarak adlandırılır.
Eski yığın oluşturma
Navigation 3'te eski yığın aslında içerik barındırmaz. Bunun yerine, anahtar olarak bilinen içerik referansları barındırır. 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ı eski yığına göndererek gezinmek kolaydır.
- Anahtarlar serileştirilebilir olduğu sürece eski yığın, kalıcı depolama alanına kaydedilebilir. Böylece yapılandırma değişiklikleri ve işlem sonlandırma sırasında korunabilir. Bu önemlidir, çünkü kullanıcılar uygulamanızdan ayrılıp daha sonra geri döndüklerinde aynı içeriğin gösterilmesini ve kaldıkları yerden devam etmeyi beklerler. Daha fazla bilgi için Eski yığınınızı kaydetme başlıklı makaleyi inceleyin.
Navigation 3 API'deki önemli bir kavram, eski yığının size ait olmasıdır. Kitaplık:
- Eski yığınınızın, anlık görüntü durumu destekli bir
List<T>olmasını bekler. BuradaT, eski yığınınızınkeystürüdür.Anykullanabilir veya kendi daha güçlü türde anahtarlarınızı sağlayabilirsiniz. "Push" veya "pop" terimlerini gördüğünüzde, temel uygulama bir listenin sonuna öğe eklemek veya kaldırmaktır. - Eski yığınınızı gözlemler ve durumunu
NavDisplaykullanarak kullanıcı arayüzüne yansıtır.
Aşağıdaki örnekte, anahtarların ve eski yığının nasıl oluşturulacağı ve kullanıcı gezinme etkinliklerine yanıt olarak eski yığının 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() }
Anahtarları içeriğe çözümleme
İçerik, Navigation 3'te composable işlev içeren bir sınıf olan NavEntry kullanılarak modellenir. Kullanıcının ileri ve geri gidebileceği tek bir içerik parçası olan hedefi temsil eder.
NavEntry, içerikle ilgili bilgileri barındıran meta veriler de içerebilir. Bu meta veriler, NavDisplay gibi kapsayıcı nesneler tarafından okunarak NavEntry içeriğinin nasıl gösterileceğine karar vermelerine yardımcı olabilir. Örneğin, meta veriler belirli bir NavEntry için varsayılan animasyonları geçersiz kılmak amacıyla kullanılabilir. NavEntry
metadata, String anahtarlarını Any değerleriyle eşleyerek çok yönlü veri depolama imkanı sunar.
key öğesini NavEntry öğesine dönüştürmek için bir giriş sağlayıcı oluşturun. Bu işlev, key kabul eder ve bu key için bir NavEntry döndürür. Genellikle NavDisplay oluşturulurken lambda parametresi olarak tanımlanır.
Giriş sağlayıcı oluşturmanın iki yolu vardır: Doğrudan lambda işlevi oluşturarak veya entryProvider DSL'yi kullanarak.
Doğrudan giriş sağlayıcı işlevi oluşturma
Genellikle her anahtarınız için bir dal içeren when ifadesini 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üz için 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şturucu işlevini kullanın. Ayrıca, anahtar bulunamazsa varsayılan yedek davranışı (hata döndürme) içerir.
entryProvider = entryProvider { entry<ProductList> { Text("Product List") } entry<ProductDetail>( metadata = mapOf("extraDataKey" to "extraDataValue") ) { key -> Text("Product ${key.id} ") } }
Snippet'te şunlara dikkat edin:
entry, belirli bir tür ve composable içerikleNavEntrytanımlamak için kullanılır.entry,NavEntry.metadatadeğerini ayarlamak için birmetadataparametresi kabul eder.
Eski yığını görüntüleme
Eski 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 NavDisplay, eski yığınınızı gözlemler ve kullanıcı arayüzünü buna göre günceller. Aşağıdaki parametrelerle oluşturun:
- Eski yığınınız: Bu,
SnapshotStateList<T>türünde olmalıdır. BuradaT, eski yığın anahtarlarınızın türüdür. Bu, gözlemlenebilir birListolduğundan değiştiğindeNavDisplayöğesinin yeniden oluşturulmasını tetikler. - Eski yığınınızdaki anahtarları
NavEntrynesnelerine dönüştürmek için birentryProvider. - İsteğe bağlı olarak
onBackparametresine bir lambda sağlayın. Bu yöntem, kullanıcı bir geri etkinliği tetiklediğinde çağrılır.
Aşağıdaki örnekte NavDisplay oluşturma işlemi 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 bir düzende eski yığının en üstündeki NavEntry öğesini gösterir. Aşağıdaki kayıtta bu uygulamanın çalıştığı gösterilmektedir:
NavDisplay iki hedefle varsayılan davranış.Hedef yaşam döngüsü
NavDisplay, hem Scene 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 LifecycleOwner'ler 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
şu şekilde belirlenir:
Yer paylaşımı olmayan sahneler için:
RESUMED: Yalnızca sahne geçişi tamamlandığında ve üzerinde etkin bir yer paylaşımı sahnesi gösterilmediğinde izin verilir.STARTED: İleri veya geri gitme gibi sahne geçişleri sırasında ya da bir yer paylaşımla kaplandığındaSTARTEDile sınırlıdır.
İletişim kutuları veya alt sayfalar gibi yer paylaşımlı sahneler için:
RESUMED: Yalnızca en üstteki, şu anda etkin olan yer paylaşımı sahnesi için izin verilir.STARTED: Daha yeni bir yer paylaşımıyla kapsanan tüm 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,
eski yığındaki varlığına göre yönetir:
RESUMED: Giriş, mevcut eski yığında varsa yaşam döngüsününRESUMEDdeğerine kadar çıkmasına izin verilir (sahne düzeyindeki sınıra tabidir).CREATED: Giriş artık eski yığında değilse (ör. çıkarılmış ancak animasyonla çıkarken ekranda hâlâ oluşturuluyorsa) kitaplık, yaşam döngüsünü kesin olarakCREATEDile sınırlandırır. Bu sınır, arka plandaki veya çıkış yapan girişlerin, çıkış geçişlerini tamamlarken akışları toplama ya daRESUMEDveyaSTARTEDdurumlarına bağlı eş yordamları başlatma gibi etkin işleri yürütmeyi durdurmasını sağlar.
Nasıl birleştirilirler?
Örneğin, bir NavEntry öğesinin nihai yaşam döngüsü durumu şu şekilde çözümlenir:
| Senaryo | Sahne Düzeyinde Sınır | Başlangıç Düzeyi Sınırı | Geçerli Sınır |
|---|---|---|---|
| Etkin giriş, sabit ekran (geçiş veya yer paylaşımı yok) | RESUMED |
RESUMED |
RESUMED |
| Geçiş sırasında etkin giriş (girişe veya çıkışa doğru gezinme) | STARTED |
RESUMED |
STARTED |
| Etkin giriş, bir yer paylaşımlı öğe tarafından kapatılmış (örneğin, bir iletişim kutusu açık) | STARTED |
RESUMED |
STARTED |
| Açılan giriş, animasyonla çıkıyor | STARTED veya RESUMED |
CREATED |
CREATED |
Özet
Aşağıdaki şemada, verilerin Navigation 3'teki çeşitli nesneler arasında nasıl aktığı gösterilmektedir:
Gezinme etkinlikleri değişiklikleri başlatır. Anahtarlar, kullanıcı etkileşimlerine yanıt olarak eski yığına eklenir veya eski yığından kaldırılır.
Eski yığın durumundaki değişiklik, içerik alma işlemini tetikler.
NavDisplay(eski yığın oluşturan bir composable), eski yığını gözlemler. Varsayılan yapılandırmasında, en üstteki eski yığın girişini tek bölmeli bir düzende gösterir. Eski 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 sağlar. Giriş sağlayıcı, bir anahtarı
NavEntrydeğerine çözümleyen bir işlevdir.NavDisplayanahtarını alan giriş sağlayıcı, hem anahtarı hem de içeriği barındıran ilişkiliNavEntrydeğerini sağlar.İçerik gösterilir.
NavDisplay,NavEntrydeğerini alır ve içeriği gösterir.