İç içe yerleştirilmiş grafikler

Uygulamanızdaki giriş akışları, sihirbazlar veya diğer alt akışlar genellikle en iyi şekilde iç içe yerleştirilmiş gezinme grafikleri olarak gösterilir. Bağımsız alt gezinme akışlarını bu şekilde iç içe yerleştirmek, uygulamanızın kullanıcı arayüzünün ana akışının anlaşılması ve yönetilmesini kolaylaştırır.

Buna ek olarak, iç içe yerleştirilmiş grafikler yeniden kullanılabilir. Bunlar aynı zamanda bir kapsayıcılık düzeyi de sağlar. İç içe yerleştirilmiş grafiğin dışındaki hedeflerin, iç içe yerleştirilmiş grafikteki hedeflerin hiçbirine doğrudan erişimi yoktur. Bunun yerine, iç içe yerleştirilmiş grafiğin kendisinde navigate() gerekir. Burada, dahili mantık grafiğin geri kalanını etkilemeden değişebilmektedir.

Örnek

Uygulamanızın üst düzey gezinme grafiği, kullanıcının uygulamayı başlatırken gördüğü ilk hedefle başlamalı ve uygulamanızda gezinirken gördükleri hedefleri içermelidir.

Şekil 1. Üst düzey gezinme grafiği.

Örnek olarak Şekil 1'deki üst düzey gezinme grafiğini kullanarak kullanıcının title_screen ve kaydet ekranlarını yalnızca uygulama ilk kez başlatıldığında görmesini istemek istediğinizi varsayalım. Daha sonra, kullanıcı bilgileri depolanır ve uygulamayı sonraki başlatmalarda doğrudan eşleşme ekranına yönlendirmeniz gerekir.

En iyi uygulama olarak eşleşme ekranını üst düzey gezinme grafiğinin başlangıç hedefi olarak ayarlayın ve başlık ile ekranları iç içe yerleştirilmiş bir grafiğe taşıyın.

Şekil 2. Üst düzey gezinme grafiği artık iç içe yerleştirilmiş bir grafik içeriyor.

Eşleşme ekranı açıldığında kayıtlı bir kullanıcı olup olmadığını kontrol edin. Kullanıcı kayıtlı değilse kullanıcıyı kayıt ekranına gidin.

Koşullu gezinme senaryoları hakkında daha fazla bilgi için Koşullu gezinme bölümüne bakın.

Oluştur

Oluştur'u kullanarak iç içe yerleştirilmiş gezinme grafiği oluşturmak için NavGraphBuilder.navigation() işlevini kullanın. Bir grafiğe hedef eklerken navigation() aynen NavGraphBuilder.composable() ve NavGraphBuilder.dialog() işlevleri gibi kullanılır.

Temel fark, navigation ürününün yeni bir hedef yerine iç içe yerleştirilmiş bir grafik oluşturmasıdır. Daha sonra, iç içe yerleştirilmiş grafiğe hedefler eklemek için navigation lambda içinde composable ve dialog çağırırsınız.

Aşağıdaki snippet'in Şekil 2'deki grafiği Oluşturma özelliğini kullanarak nasıl uyguladığını düşünün:

NavHost(navController, startDestination = "title_screen") {
    composable("title_screen") {
        TitleScreen(
            onPlayClicked = { navController.navigate("register") },
            onLeaderboardsClicked = { /* Navigate to leaderboards */ }
        )
    }
    composable("register") {
        RegisterScreen(
            onSignUpComplete = { navController.navigate("gameInProgress") }
        )
    }
    navigation(startDestination = "match", route = "gameInProgress") {
        composable("match") {
            MatchScreen(
                onStartGame = { navController.navigate("in_game") }
            )
        }
        composable("in_game") {
            InGameScreen(
                onGameWin = { navController.navigate("results_winner") },
                onGameLose = { navController.navigate("game_over") }
            )
        }
        composable("results_winner") {
            ResultsWinnerScreen(
                onNextMatchClicked = {
                    navController.navigate("match") {
                        popUpTo("match") { inclusive = true }
                    }
                },
                onLeaderboardsClicked = { /* Navigate to leaderboards */ }
            )
        }
        composable("game_over") {
            GameOverScreen(
                onTryAgainClicked = {
                    navController.navigate("match") {
                        popUpTo("match") { inclusive = true }
                    }
                }
            )
        }
    }
}

İç içe yerleştirilmiş bir hedefe doğrudan gitmek için route özelliğini diğer herhangi bir hedefe giderken kullandığınız gibi kullanın. Bunun nedeni, rotaların her ekranda gidebileceği genel bir kavram olmasıdır:

navController.navigate("match")

Uzantı işlevleri

NavGraphBuilder üzerindeki bir uzantı işlevini kullanarak grafiğe hedefler ekleyebilirsiniz. Bu uzantı işlevlerini, önceden oluşturulmuş navigation, composable ve dialog uzantı yöntemleriyle birlikte kullanabilirsiniz.

Örneğin, önceki bölümde gösterilen iç içe yerleştirilmiş grafiği eklemek için bir uzantı işlevi kullanabilirsiniz:

fun NavGraphBuilder.addNestedGraph(navController: NavController) {
    navigation(startDestination = "match", route = "gameInProgress") {
        composable("match") {
            MatchScreen(
                onStartGame = { navController.navigate("in_game") }
            )
        }
        composable("in_game") {
            InGameScreen(
                onGameWin = { navController.navigate("results_winner") },
                onGameLose = { navController.navigate("game_over") }
            )
        }
        composable("results_winner") {
            ResultsWinnerScreen(
                onNextMatchClicked = { navController.navigate("match") },
                onLeaderboardsClicked = { /* Navigate to leaderboards */ }
            )
        }
        composable("game_over") {
            GameOverScreen(
                onTryAgainClicked = { navController.navigate("match") }
            )
        }
    }
}

Daha sonra, satır içi gezinme yöntemini çağırmak yerine, NavHost öğesine ilettiğiniz lambdada bu işlevi çağırabilirsiniz. Aşağıdaki örnekte bu durum gösterilmektedir:

@Composable
fun MyApp() {
    val navController = rememberNavController()
    NavHost(navController, startDestination = "title_screen") {
        composable("title_screen") {
            TitleScreen(
                onPlayClicked = { navController.navigate("register") },
                onLeaderboardsClicked = { /* Navigate to leaderboards */ }
            )
        }
        composable("register") {
            RegisterScreen(
                onSignUpComplete = { navController.navigate("gameInProgress") }
            )
        }

        // Add the nested graph using the extension function
        addNestedGraph(navController)
    }
}

XML

XML kullanırken iç içe yerleştirilmiş grafiğinizi oluşturmak için Gezinme Düzenleyici'yi kullanabilirsiniz. Bunun için aşağıdaki adımları uygulayın:

  1. Gezinme Düzenleyici'de Üst Karakter tuşunu basılı tutun ve iç içe yerleştirilmiş grafiğe dahil etmek istediğiniz hedefleri tıklayın.
  2. İçerik menüsünü açmak için sağ tıklayın ve Yuvalanmış Grafiğe Taşı > Yeni Grafik'i seçin. Hedefler iç içe yerleştirilmiş bir grafik içinde gösterilir. Şekil 2'de, Gezinme Düzenleyici'deki iç içe yerleştirilmiş bir grafik gösterilmektedir:

    Şekil 2. Gezinme düzenleyicisinde iç içe yerleştirilmiş grafik
  3. İç içe yerleştirilmiş grafiği tıklayın. Aşağıdaki özellikler, Özellikler panelinde görünür:

    • Tür: "Yuvalanmış Grafik"i içerir
    • Kimlik: İç içe yerleştirilmiş grafik için sistem tarafından atanan kimliği içerir. Bu kimlik, kodunuzdaki iç içe yerleştirilmiş grafiğe referans vermek için kullanılır.
  4. Hedeflerini görmek için iç içe yerleştirilmiş grafiği çift tıklayın.

  5. XML görünümüne geçmek için Metin sekmesini tıklayın. Grafiğe, iç içe yerleştirilmiş bir gezinme grafiği eklenmiştir. Bu gezinme grafiğinin kendi navigation öğeleriyle birlikte kendi kimliği vardır ve iç içe yerleştirilmiş grafikteki ilk hedefe işaret eden bir startDestination özelliği bulunur:

    <?xml version="1.0" encoding="utf-8"?>
    <navigation xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:android="http://schemas.android.com/apk/res/android"
        app:startDestination="@id/mainFragment">
        <fragment
            android:id="@+id/mainFragment"
            android:name="com.example.cashdog.cashdog.MainFragment"
            android:label="fragment_main"
            tools:layout="@layout/fragment_main" >
            <action
                android:id="@+id/action_mainFragment_to_sendMoneyGraph"
                app:destination="@id/sendMoneyGraph" />
            <action
                android:id="@+id/action_mainFragment_to_viewBalanceFragment"
                app:destination="@id/viewBalanceFragment" />
        </fragment>
        <fragment
            android:id="@+id/viewBalanceFragment"
            android:name="com.example.cashdog.cashdog.ViewBalanceFragment"
            android:label="fragment_view_balance"
            tools:layout="@layout/fragment_view_balance" />
        <navigation android:id="@+id/sendMoneyGraph" app:startDestination="@id/chooseRecipient">
            <fragment
                android:id="@+id/chooseRecipient"
                android:name="com.example.cashdog.cashdog.ChooseRecipient"
                android:label="fragment_choose_recipient"
                tools:layout="@layout/fragment_choose_recipient">
                <action
                    android:id="@+id/action_chooseRecipient_to_chooseAmountFragment"
                    app:destination="@id/chooseAmountFragment" />
            </fragment>
            <fragment
                android:id="@+id/chooseAmountFragment"
                android:name="com.example.cashdog.cashdog.ChooseAmountFragment"
                android:label="fragment_choose_amount"
                tools:layout="@layout/fragment_choose_amount" />
        </navigation>
    </navigation>
    
  6. Kodunuzda, kök grafiği iç içe yerleştirilmiş grafiğe bağlayan işlemin kaynak kimliğini iletin:

    Kotlin

    view.findNavController().navigate(R.id.action_mainFragment_to_sendMoneyGraph)
    

    Java

    Navigation.findNavController(view).navigate(R.id.action_mainFragment_to_sendMoneyGraph);
    
  7. Tasarım sekmesine dönün ve Kök'ü tıklayarak kök grafiğe dönün.

Diğer gezinme grafiklerine referans olarak şunları ekleyin:

Grafik yapınızı modüler hale getirmenin diğer bir yolu, üst gezinme grafiğine <include> öğesi kullanarak bir grafiği başka bir içine dahil etmektir. Bu, yeniden kullanılabilirliği en üst düzeye çıkararak dahil edilen grafiğin ayrı bir modülde veya projede birlikte tanımlanmasını sağlar.

<include> öğesini nasıl kullanabileceğiniz aşağıdaki snippet'te gösterilmektedir:

<!-- (root) nav_graph.xml -->
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_graph"
    app:startDestination="@id/fragment">

    <strong><include app:graph="@navigation/included_graph" /></strong>

    <fragment
        android:id="@+id/fragment"
        android:name="com.example.myapplication.BlankFragment"
        android:label="Fragment in Root Graph"
        tools:layout="@layout/fragment_blank">
        <strong><action
            android:id="@+id/action_fragment_to_second_graph"
            app:destination="@id/second_graph" /></strong>
    </fragment>

    ...
</navigation>
<!-- included_graph.xml -->
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    <strong>android:id="@+id/second_graph"</strong>
    app:startDestination="@id/includedStart">

    <fragment
        android:id="@+id/includedStart"
        android:name="com.example.myapplication.IncludedStart"
        android:label="fragment_included_start"
        tools:layout="@layout/fragment_included_start" />
</navigation>

Ek kaynaklar

Gezinme hakkında daha fazla bilgi edinmek için aşağıdaki ek kaynaklara bakın.

Sana Özel

Codelab uygulamaları

Videolar