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)
}

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 rememberSaveableStateHolderNavEntryDecorator() öğesini entryDecorators listesine ekleyin.
  3. NavDisplay öğenize başka parametreler ekleyin.

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