Gezinme ve arka plan yığını

NavController, kullanıcının ziyaret ettiği hedefleri içeren bir "geri yığını" barındırır. Kullanıcı uygulamanızdaki ekranlar arasında gezinirken NavController, geri yığına hedefler ekler ve hedefleri geri yığından kaldırır.

Geriye doğru yığın, "son giren ilk çıkar" veri yapısıdır. Bu nedenle NavController, öğeleri yığının en üstüne iter ve yığının en üstünden çıkarır.

Temel davranış

Arka yığın davranışıyla ilgili olarak dikkate almanız gereken temel bilgiler şunlardır:

  • İlk hedef: Kullanıcı uygulamayı açtığında NavController, ilk hedefi geri yığınının en üstüne iter.
  • Yığına gönderme: Her arama NavController.navigate(), belirtilen hedefi yığının en üstüne gönderir.
  • En popüler hedef: Yukarı veya Geri'ye dokunulduğunda sırasıyla NavController.navigateUp() ve NavController.popBackStack() yöntemleri çağrılır. En üstteki hedefi yığından çıkarır. Yukarı ve Geri arasındaki fark hakkında daha fazla bilgi için Gezinme İlkeleri sayfasına bakın.

Geri döndürme

NavController.popBackStack() yöntemi, geçerli hedefi eski yığından çıkarmaya ve önceki hedefe gitmeye çalışır. Bu işlem, kullanıcıyı gezinme geçmişinde bir adım geriye götürür. Hedefe başarıyla geri dönülüp dönülmediğini gösteren bir boole değeri döndürür.

Belirli bir hedefe geri dönme

Belirli bir hedefe gitmek için popBackStack() simgesini de kullanabilirsiniz. Bunu yapmak için aşırı yüklemelerinden birini kullanın. Tam sayı id veya dize route gibi bir tanımlayıcı iletmenize olanak tanıyan çeşitli yöntemler vardır. Bu aşırı yüklemeler, kullanıcıyı belirli tanımlayıcıyla ilişkili hedefe yönlendirir. En önemlisi, yığın üzerinde bu hedefin üzerindeki her şeyi çıkarırlar.

Bu aşırı yüklemeler bir inclusive boole değeri de alır. Bu, NavController öğesinin, belirtilen hedefe gidildikten sonra eski yığından da çıkarılıp çıkarılmayacağını belirler.

Örnek olarak şu kısa snippet'i inceleyin:

navController.popBackStack(R.id.destinationId, true)

Burada NavController, destinationId tam sayı kimliğine sahip hedefle geri döner. inclusive bağımsız değişkeninin değeri true olduğundan NavController, verilen hedefi eski yığından da çıkarır.

Başarısız olan geri getirme işlemlerini ele alma

popBackStack() döndüğünde false, NavController.getCurrentDestination()'ye yapılan sonraki çağrı null değerini döndürür. Bu, uygulamanın son hedefi geri yığından çıkardığı anlamına gelir. Bu durumda kullanıcı yalnızca boş bir ekran görür.

Bu durum aşağıdaki durumlarda ortaya çıkabilir:

  • popBackStack(), yığından hiçbir öğe çıkarmadı.
  • popBackStack() eski yığından bir hedef çıkardı ve yığın artık boş.

Bu sorunu çözmek için yeni bir hedefe gitmeniz veya finish() etkinliğini çağırarak etkinliği sonlandırmanız gerekir. Aşağıdaki snippet bu durumu gösterir:

kotlin

...

if (!navController.popBackStack()) {
    // Call finish() on your Activity
    finish()
}

java

...

if (!navController.popBackStack()) {
    // Call finish() on your Activity
    finish();
}

Bir hedefe gitme

Bir hedeften diğerine giderken hedefleri geri yığından kaldırmak için ilişkili navigate() işlev çağrısına popUpTo() bağımsız değişkenini ekleyin. popUpTo(), navigate() çağrısının bir parçası olarak gezinme kitaplığına arka yığından bazı hedefleri kaldırması talimatını verir. Parametre değeri, geri yığında bir hedefin tanımlayıcısıdır. Tanımlayıcı bir tam sayı id veya dize route olabilir.

inclusive parametresi için true değerine sahip bir bağımsız değişken ekleyerek popUpTo() içinde belirttiğiniz hedefin geri yığında da kaldırılması gerektiğini belirtebilirsiniz.

Bunu programatik olarak uygulamak için popUpTo() değerini navigate() öğesine NavOptions kapsamında iletin. inclusive değeri true olarak ayarlanmalıdır. Bu özellik hem Oluşturma hem de Görünümler'de çalışır.

Pop-up gösterilirken durumu kaydetme

Bir hedefe gitmek için popUpTo simgesini kullandığınızda, geri yığını ve geri yığınından çıkarılan tüm hedeflerin durumlarını isteğe bağlı olarak kaydedebilirsiniz. Daha sonra bu hedefe gittiğinizde geri yığını ve hedefleri geri yükleyebilirsiniz. Bu, belirli bir hedef için durumu korumanıza ve birden fazla geri yığınına sahip olmanıza olanak tanır.

Bunu programatik olarak yapmak için popUpTo öğesini gezinme seçeneklerinize eklerken saveState = true öğesini belirtin.

Ayrıca, geri yığını ve hedefle ilişkili durumu otomatik olarak geri yüklemek için gezinme seçeneklerinizde restoreState = true değerini de belirtebilirsiniz.

Örneğin:

navController.navigate(
    route = route,
    navOptions =  navOptions {
        popUpTo<A>{ saveState = true }
        restoreState = true
    }
)

Durumu XML'de kaydetme ve geri yükleme özelliğini etkinleştirmek için ilişkili action içinde popUpToSaveState öğesini true, restoreState öğesini ise true olarak tanımlayın.

XML örneği

Bir işlem kullanılarak XML'deki popUpTo örneğini aşağıda görebilirsiniz:

<action
  android:id="@+id/action_a_to_b"
  app:destination="@id/b"
  app:popUpTo="@+id/a"
  app:popUpToInclusive="true"
  app:restoreState=”true”
  app:popUpToSaveState="true"/>

Oluşturma örneği

Aşağıda, Oluştur'daki aynı işlevin tam bir örneği verilmiştir:

@Composable
fun MyAppNavHost(
    modifier: Modifier = Modifier,
    navController: NavHostController = rememberNavController(),
    startDestination: Any = A
) {
    NavHost(
        modifier = modifier,
        navController = navController,
        startDestination = startDestination
    ) {
        composable<A> {
            DestinationA(
                onNavigateToB = {
                // Pop everything up to, and including, the A destination off
                // the back stack, saving the back stack and the state of its
                // destinations.
                // Then restore any previous back stack state associated with
                // the B destination.
                // Finally navigate to the B destination.
                    navController.navigate(route = B) {
                        popUpTo<A> {
                            inclusive = true
                            saveState = true
                        }
                        restoreState = true
                    }
                },
            )
        }
        composable<B> { DestinationB(/* ... */) }
    }
}

@Composable
fun DestinationA(onNavigateToB: () -> Unit) {
    Button(onClick = onNavigateToB) {
        Text("Go to A")
    }
}

Daha ayrıntılı olarak, NavController.navigate()'ı çağırma şeklinizi aşağıdaki yöntemlerle değiştirebilirsiniz:

// Pop everything up to the destination_a destination off the back stack before
// navigating to the "destination_b" destination
navController.navigate("destination_b") {
    popUpTo("destination_a")
}

// Pop everything up to and including the "destination_a" destination off
// the back stack before navigating to the "destination_b" destination
navController.navigate("destination_b") {
    popUpTo("destination_a") { inclusive = true }
}

// Navigate to the "search” destination only if we’re not already on
// the "search" destination, avoiding multiple copies on the top of the
// back stack
navController.navigate("search") {
    launchSingleTop = true
}

NavController.navigate()'ya seçenek aktarma hakkında genel bilgi için Seçeneklerle gezinme kılavuzu'na bakın.

İşlemleri kullanarak pop yapma

Bir işlemi kullanarak gezinirken isteğe bağlı olarak eski yığından ek hedefler çıkarabilirsiniz. Örneğin, uygulamanızda ilk giriş akışı varsa kullanıcı giriş yaptıktan sonra, Geri düğmesi kullanıcıları giriş akışına geri götürmemesi için girişle ilgili tüm hedefleri eski yığından çıkarmanız gerekir.

Ek kaynaklar

Daha fazla bilgi için aşağıdaki sayfaları inceleyin:

  • Dairesel gezinme: Gezinme akışlarının dairesel olduğu durumlarda aşırı dolu bir geri yığını nasıl önleyeceğinizi öğrenin.
  • İletişim hedefleri: İletişim hedeflerinin, eski yığını yönetme şeklinize nasıl benzersiz hususlar kattığı hakkında bilgi edinin.