Gezinme durumunu kaydetme ve yönetme

Aşağıdaki bölümlerde, eski yığınınızı kaydetme ve eski yığınınızdaki girişlerle ilişkili durumu depolama stratejileri açıklanmaktadır.

Eski yığınınızı kaydetme

Uygulamanızın gezinme durumunun, yapılandırma değişiklikleri ve işlem sonlandırma dahil olmak üzere çeşitli yaşam döngüsü etkinliklerinde kalıcı olmasını sağlamak, iyi bir kullanıcı deneyimi için çok önemlidir. Navigation 3'te eski yığın size aittir. Bu nedenle, nasıl oluşturmanız veya kaydetmeniz gerektiği konusunda katı kurallar yoktur. Ancak Navigation 3, kaydedilebilir bir eski yığın sağlayan kullanışlı bir yöntem sunar: rememberNavBackStack.

rememberNavBackStack kodunu kullanın

rememberNavBackStack composable işlevi, yapılandırma değişiklikleri ve işlem sonlandırma boyunca kalıcı olan bir eski yığın oluşturmak için tasarlanmıştır.

rememberNavBackStack öğesinin doğru şekilde çalışması için eski yığınınızdaki her anahtarın belirli koşullara uyması gerekir:

  • NavKey arayüzünü uygulayın: Eski yığındaki her anahtar, NavKey arayüzünü uygulamalıdır. Bu, anahtarın kaydedilebileceğini kitaplığa bildiren bir işaretleyici arayüzü görevi görür.
  • @Serializable ek açıklamasına sahip olun: NavKey kodunu uygulamanın yanı sıra, önemli sınıflarınız ve nesneleriniz @Serializable ek açıklamasıyla işaretlenmelidir.

Aşağıdaki snippet'te rememberNavBackStack öğesinin doğru uygulanmış bir örneği gösterilmektedir:

@Serializable
data object Home : NavKey

@Composable
fun NavBackStack() {
    val backStack = rememberNavBackStack(Home)
}

NavKey alt türlerini içeren bir geri yığını hatırlayın.

rememberNavBackStack composable işlevi, NavBackStack<NavKey> döndürür. Uygulamanız, tüm anahtarlarının devralındığı kendi NavKey alt türünü tanımlıyorsa özel bir remember işlevi uygulayarak bu türü koruyabilirsiniz.

@Serializable
sealed interface MyAppNavKey : NavKey

@Serializable
data object ScreenA: MyAppNavKey

@Serializable
data class ScreenB(val id: String): MyAppNavKey

@Composable
fun rememberMyAppNavBackStack(vararg elements: MyAppNavKey): NavBackStack<MyAppNavKey> {
    return rememberSerializable(serializer = serializer()) {
        NavBackStack(*elements)
    }
}

@Composable
fun MyApp() {
    // defaultNavBackStack is NavBackStack<NavKey>
    val defaultNavBackStack = rememberNavBackStack(ScreenA)
    // myAppNavBackStack is NavBackStack<MyAppNavKey>
    val myAppNavBackStack = rememberMyAppNavBackStack(ScreenA)
}

Açık polimorfizmi ele alma da dahil olmak üzere daha fazla örnek için NavBackStackSamples başlıklı makaleyi inceleyin.

Alternatif: ViewModel içinde depolama

Eski yığını yönetmenin bir diğer yolu, yığını ViewModel içinde saklamaktır. ViewModel veya başka bir özel depolama alanı kullanırken işlem sonlandırma sırasında verilerin kalıcı olması için şunları yapmanız gerekir:

  • Anahtarlarınızın serileştirilebilir olduğundan emin olun: rememberNavBackStack kodunda olduğu gibi gezinme anahtarlarınızın da serileştirilebilir olması gerekir.
  • Serileştirme ve seri durumdan çıkarma işlemlerini manuel olarak gerçekleştirin: Uygulamanız arka plana geçerken veya yeniden yüklenirken, her anahtarın serileştirilmiş bir temsilini kalıcı depolama alanına (ör. SharedPreferences, veritabanı veya dosya) manuel olarak kaydetmek ve serileştirmesini kaldırmak sizin sorumluluğunuzdadır.

ViewModel kodlarını NavEntry kapsamına alma

ViewModels, ekran döndürme gibi yapılandırma değişikliklerinde kullanıcı arayüzüyle ilgili durumu korumak için kullanılır. Varsayılan olarak ViewModels, en yakın ViewModelStoreOwner kapsamına alınır. Bu genellikle Activity veya Fragment olur.

Ancak ViewModel kapsamını tüm Activity yerine eski yığında belirli bir NavEntry (ör. belirli bir ekran veya hedef) ile sınırlamak isteyebilirsiniz. Bu, ViewModel kodunun durumunun yalnızca söz konusu NavEntry eski yığında yer alırken korunmasını ve NavEntry çıkarıldığında temizlenmesini sağlar.

androidx.lifecycle:lifecycle-viewmodel-navigation3 eklenti kitaplığı, bu işlemi kolaylaştıran bir NavEntryDecorator sunar. Bu dekoratör, her NavEntry için bir ViewModelStoreOwner sağlar. Bir ViewModel oluşturduğunuzda (ör. Compose'da viewModel() kullanarak) otomatik olarak eski yığındaki söz konusu NavEntry kodunun anahtarıyla sınırlandırılır.NavEntry Bu, NavEntry eski yığına eklendiğinde ViewModel oluşturulacağı ve kaldırıldığında temizleneceği anlamına gelir.

NavEntryDecorator kodunu kullanarak ViewModel kodlarını NavEntry kapsamına almak için aşağıdaki adımları uygulayın:

  1. androidx.lifecycle:lifecycle-viewmodel-navigation3 bağımlılığını app/build.gradle.kts dosyanıza ekleyin.
  2. NavDisplay oluştururken varsayılan rememberSaveableStateHolderNavEntryDecorator()entryDecorators listesine ekleyin.
  3. rememberViewModelStoreNavEntryDecorator() uygulamasını entryDecorators listesine ekleyin.

NavDisplay(
    entryDecorators = listOf(
        // Add the default decorators for managing scenes and saving state
        rememberSaveableStateHolderNavEntryDecorator(),
        // Then add the view model store decorator
        rememberViewModelStoreNavEntryDecorator()
    ),
    backStack = backStack,
    entryProvider = entryProvider { },
)