Uyarlanabilir gezinme oluşturma

Çoğu uygulamanın, uygulamanın birincil gezinme kullanıcı arayüzü üzerinden erişilebilen birkaç üst düzey hedefi vardır. Standart bir telefon ekranı gibi kompakt pencerelerde hedefler genellikle pencerenin alt kısmındaki bir gezinme çubuğunda gösterilir. Bir tabletteki tam ekran uygulama gibi genişletilmiş bir pencerede, cihazın sol ve sağ taraflarını tutarken gezinme kontrollerine ulaşmak daha kolay olduğundan genellikle uygulamanın yanındaki bir gezinme çubuğu daha iyi bir seçimdir.

NavigationSuiteScaffold, WindowSizeClass temelinde uygun gezinme kullanıcı arayüzü composable'ını göstererek gezinme kullanıcı arayüzleri arasında geçiş yapmayı kolaylaştırır. Çalışma zamanında pencere boyutu değişiklikleri sırasında kullanıcı arayüzünü dinamik olarak değiştirme de buna dahildir. Varsayılan davranış, aşağıdaki kullanıcı arayüzü bileşenlerinden birini göstermektir:

  • Genişlik veya yükseklik kompakt ise ya da cihaz masaüstü duruşundaysa gezinme çubuğu
  • Diğer her şey için gezinme sütunu
1.Şekil NavigationSuiteScaffold, kompakt pencerelerde bir gezinme çubuğu gösterir.
Şekil 2. NavigationSuiteScaffold, genişletilmiş pencerelerde gezinme sütunu gösterir.

Bağımlılık ekleme

NavigationSuiteScaffold, Material3 uyarlanabilir gezinme paketi kitaplığının bir parçasıdır. Uygulamanızın veya modülünüzün build.gradle dosyasında kitaplık için bağımlılık ekleyin:

Kotlin

implementation("androidx.compose.material3:material3-adaptive-navigation-suite")

Groovy

implementation 'androidx.compose.material3:material3-adaptive-navigation-suite'

İskele oluşturma

NavigationSuiteScaffold'nın iki ana bölümü vardır: gezinme paketi öğeleri ve seçilen hedefin içeriği. Gezinme paketi öğelerini doğrudan bir composable'da tanımlayabilirsiniz ancak bunları başka bir yerde (ör. bir enum'da) tanımlamak yaygındır:

enum class AppDestinations(
    @StringRes val label: Int,
    val icon: ImageVector,
    @StringRes val contentDescription: Int
) {
    HOME(R.string.home, Icons.Default.Home, R.string.home),
    FAVORITES(R.string.favorites, Icons.Default.Favorite, R.string.favorites),
    SHOPPING(R.string.shopping, Icons.Default.ShoppingCart, R.string.shopping),
    PROFILE(R.string.profile, Icons.Default.AccountBox, R.string.profile),
}

NavigationSuiteScaffold özelliğini kullanmak için mevcut hedefi izlemeniz gerekir. Bunu rememberSaveable kullanarak yapabilirsiniz:

var currentDestination by rememberSaveable { mutableStateOf(AppDestinations.HOME) }

Aşağıdaki örnekte, navigationSuiteItems parametresi (type NavigationSuiteScope), tek bir hedef için gezinme kullanıcı arayüzünü tanımlamak üzere item işlevini kullanır. Hedef kullanıcı arayüzü; gezinme çubukları, raylar ve çekmecelerde kullanılır. Gezinme öğeleri oluşturmak için AppDestinations (önceki snippet'te tanımlanmıştır) üzerinde döngü oluşturursunuz:

NavigationSuiteScaffold(
    navigationSuiteItems = {
        AppDestinations.entries.forEach {
            item(
                icon = {
                    Icon(
                        it.icon,
                        contentDescription = stringResource(it.contentDescription)
                    )
                },
                label = { Text(stringResource(it.label)) },
                selected = it == currentDestination,
                onClick = { currentDestination = it }
            )
        }
    }
) {
    // TODO: Destination content.
}

Hedef içerik lambda'sında, hangi kullanıcı arayüzünün gösterileceğine karar vermek için currentDestination değerini kullanın. Uygulamanızda bir navigasyon kitaplığı kullanıyorsanız uygun hedefi göstermek için bu kitaplığı burada kullanın. Bir "when" ifadesi yeterli olabilir:

NavigationSuiteScaffold(
    navigationSuiteItems = { /*...*/ }
) {
    // Destination content.
    when (currentDestination) {
        AppDestinations.HOME -> HomeDestination()
        AppDestinations.FAVORITES -> FavoritesDestination()
        AppDestinations.SHOPPING -> ShoppingDestination()
        AppDestinations.PROFILE -> ProfileDestination()
    }
}

Renkleri değiştir

NavigationSuiteScaffold, iskelenin kapladığı alanın tamamında (genellikle pencerenin tamamı) Surface oluşturur. Bunun yanı sıra iskele, NavigationBar gibi belirli bir gezinme kullanıcı arayüzünü çizer. Hem yüzey hem de gezinme kullanıcı arayüzü, uygulamanızın temasında belirtilen değerleri kullanır ancak tema değerlerini geçersiz kılabilirsiniz.

containerColor parametresi, yüzeyin rengini belirtir. Varsayılan olarak, renk şemanızın arka plan rengi kullanılır. contentColor parametresi, bu yüzeydeki içeriğin rengini belirtir. Varsayılan olarak, containerColor için belirtilen öğenin "açık" rengi kullanılır. Örneğin, containerColor background rengini kullanıyorsa contentColor, onBackground rengini kullanır. Renk sisteminin işleyiş şekli hakkında daha fazla bilgi için Compose'da Material Design 3 temalandırma başlıklı makaleyi inceleyin. Bu değerleri geçersiz kılarken uygulamanızın koyu ve açık ekran modlarını desteklemesi için temanızda tanımlanan değerleri kullanın:

NavigationSuiteScaffold(
    navigationSuiteItems = { /* ... */ },
    containerColor = MaterialTheme.colorScheme.primary,
    contentColor = MaterialTheme.colorScheme.onPrimary,
) {
    // Content...
}

Navigasyon kullanıcı arayüzü, NavigationSuiteScaffold yüzeyinin önünde çizilir. Kullanıcı arayüzü renklerinin varsayılan değerleri NavigationSuiteDefaults.colors() tarafından sağlanır ancak bu değerleri geçersiz kılabilirsiniz. Örneğin, gezinme çubuğunun arka planının şeffaf olmasını ancak diğer değerlerin varsayılan olmasını istiyorsanız navigationBarContainerColor değerini geçersiz kılın:

NavigationSuiteScaffold(
    navigationSuiteItems = { /* ... */ },
    navigationSuiteColors = NavigationSuiteDefaults.colors(
        navigationBarContainerColor = Color.Transparent,
    )
) {
    // Content...
}

Son olarak, gezinme kullanıcı arayüzündeki her öğeyi özelleştirebilirsiniz. item işlevini çağırırken NavigationSuiteItemColors örneği iletebilirsiniz. Sınıf, gezinme çubuğu, gezinme rayı ve gezinme çekmecesinde yer alan öğelerin renklerini belirtir. Bu, her gezinme kullanıcı arayüzü türünde aynı renklere sahip olabileceğiniz veya renkleri ihtiyaçlarınıza göre değiştirebileceğiniz anlamına gelir. Tüm öğeler için aynı nesne örneğini kullanmak üzere renkleri NavigationSuiteScaffold düzeyinde tanımlayın ve yalnızca değiştirmek istediklerinizi geçersiz kılmak için NavigationSuiteDefaults.itemColors() işlevini çağırın:

val myNavigationSuiteItemColors = NavigationSuiteDefaults.itemColors(
    navigationBarItemColors = NavigationBarItemDefaults.colors(
        indicatorColor = MaterialTheme.colorScheme.primaryContainer,
        selectedIconColor = MaterialTheme.colorScheme.onPrimaryContainer
    ),
)

NavigationSuiteScaffold(
    navigationSuiteItems = {
        AppDestinations.entries.forEach {
            item(
                icon = {
                    Icon(
                        it.icon,
                        contentDescription = stringResource(it.contentDescription)
                    )
                },
                label = { Text(stringResource(it.label)) },
                selected = it == currentDestination,
                onClick = { currentDestination = it },
                colors = myNavigationSuiteItemColors,
            )
        }
    },
) {
    // Content...
}

Gezinme türlerini özelleştirme

NavigationSuiteScaffold öğesinin varsayılan davranışı, pencere boyutu sınıflarına göre gezinme kullanıcı arayüzünü değiştirir. Ancak bu davranışı geçersiz kılmak isteyebilirsiniz. Örneğin, uygulamanız bir feed için tek bir büyük içerik bölmesi gösteriyorsa uygulama, genişletilmiş pencereler için kalıcı bir gezinme çekmecesi kullanabilir ancak kompakt ve orta pencere boyutu sınıfları için varsayılan davranışa geri dönebilir:

val adaptiveInfo = currentWindowAdaptiveInfo()
val customNavSuiteType = with(adaptiveInfo) {
    if (windowSizeClass.isWidthAtLeastBreakpoint(WIDTH_DP_EXPANDED_LOWER_BOUND)) {
        NavigationSuiteType.NavigationDrawer
    } else {
        NavigationSuiteScaffoldDefaults.calculateFromAdaptiveInfo(adaptiveInfo)
    }
}

NavigationSuiteScaffold(
    navigationSuiteItems = { /* ... */ },
    layoutType = customNavSuiteType,
) {
    // Content...
}

Ek kaynaklar