Utwórz adaptacyjną nawigację

Większość aplikacji ma kilka głównych miejsc docelowych, które są dostępne do głównego interfejsu nawigacji aplikacji. w kompaktowych oknach, na przykład w standardowym telefonie; miejsca docelowe są zwykle wyświetlane na pasku nawigacyjnym na do dołu okna. w rozwiniętym oknie, np. w aplikacji pełnoekranowej na tabletu, kolejka nawigacyjna obok aplikacji jest zwykle lepszym wyborem, ponieważ elementy sterujące nawigacji są łatwiej dostępne po przytrzymaniu lewego i prawego rogu ekranu od urządzenia.

NavigationSuiteScaffold upraszcza przechodzenie między interfejsami nawigacyjnymi, wyświetlając odpowiedni interfejs kompozycyjny. na podstawie WindowSizeClass. Obejmuje to dynamiczne nie zmienia interfejsu użytkownika w trakcie zmiany rozmiaru okna środowiska wykonawczego. Domyślne działanie to wyświetlać jeden z tych komponentów interfejsu:

  • Pasek nawigacyjny, jeśli szerokość lub wysokość jest niewielka lub gdy urządzenie jest włożone stan stołu
  • Kolejka nawigacyjna w pozostałych przypadkach
.
. Rysunek 1. NavigationSuiteScaffold wyświetla pasek nawigacyjny w kompaktowych oknach.
.
.
Rysunek 2. NavigationSuiteScaffold wyświetla pasek nawigacji w rozwiniętych oknach.

Dodaj zależności

NavigationSuiteScaffold należy do Pakiet nawigacji adaptacyjnej Material3 bibliotece. Dodaj zależność do biblioteki w pliku build.gradle aplikacji lub moduł:

Kotlin

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

Odlotowe

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

Tworzenie rusztowania

Dwie główne części aplikacji NavigationSuiteScaffold to elementy pakietu nawigacyjnego oraz treści dla wybranego miejsca docelowego. Możesz bezpośrednio zdefiniować elementów pakietu nawigacyjnego w funkcji kompozycyjnej, ale często są one zdefiniowane w innym miejscu, na przykład w wyliczeniu:

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

Aby skorzystać z NavigationSuiteScaffold, musisz śledzić bieżące miejsce docelowe, które które można wykonać za pomocą usługi rememberSaveable:

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

W poniższym przykładzie parametr navigationSuiteItems (typ NavigationSuiteScope używa funkcji item , aby zdefiniować interfejs nawigacji dla pojedynczego miejsca docelowego. Docelowy interfejs użytkownika to na paskach nawigacyjnych, szynach i szufladach. Aby utworzyć elementy nawigacyjne, pętla na ścieżce AppDestinations (zdefiniowanej w poprzednim fragmencie):

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

W ramach funkcji lambda dotyczącej treści docelowych użyj wartości currentDestination, aby zdecydować, który interfejs wyświetlić. Jeśli korzystasz w swojej aplikacji z biblioteki nawigacyjnej, użyj jej tutaj, aby wyświetlić odpowiednie miejsce docelowe. Kiedy może Ci się to przydać:

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

Zmień kolory

NavigationSuiteScaffold tworzy Surface na całym obszarze znajduje się rusztowanie, zwykle całe okno. Do tego rusztowanie interfejsu użytkownika, np. NavigationBar. Zarówno platforma, jak i interfejs nawigacji korzystają z wartości określonych w ustawieniu motyw, ale możesz zastąpić jego wartości.

Parametr containerColor określa kolor powierzchni. Domyślny oznacza kolor tła Twojego schematu kolorów. Parametr contentColor określa kolor treści na powierzchni. Wartość domyślna to „on”. kolor dowolnego elementu określonego dla funkcji containerColor. Jeśli na przykład containerColor jest używany kolor background, a kolor contentColor jest używany przez kolor onBackground. Zobacz Tworzenie motywów Material Design 3 w usłudze Compose . Podczas zastępowania tych wartości użyj wartości zdefiniowanych w motywie, aby aplikacja obsługiwała ciemny i jasny wyświetlacz. tryby:

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

Interfejs nawigacyjny jest widoczny przed platformą NavigationSuiteScaffold. Domyślne wartości kolorów interfejsu użytkownika są dostarczane przez NavigationSuiteDefaults.colors(), a Ty również te wartości. Jeśli na przykład chcesz, aby tło: pasek nawigacyjny ma być przezroczysty, a pozostałe wartości to wartości domyślne, zastąp navigationBarContainerColor:

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

Ostatecznie każdy element można dostosować w interfejsie nawigacyjnym. Podczas wywoływania funkcji item, możesz przekazać wystąpienie NavigationSuiteItemColors Klasa określa kolory elementów na pasku nawigacyjnym, na szynie nawigacji i nawigacji szuflady. Oznacza to, że różne kolory mogą być takie same dla każdego z nich, Możesz też wybrać różne kolory w zależności od potrzeb. Określ kolory w Poziom NavigationSuiteScaffold, aby używać tej samej instancji obiektu dla wszystkich elementów i wywołaj funkcję NavigationSuiteDefaults.itemColors(), aby zastąpić tylko te, które chcesz zmienić:

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

Dostosuj typy nawigacji

Domyślne działanie funkcji NavigationSuiteScaffold zmienia interfejs nawigacji na podstawie rozmiaru okna zajęcia. Musisz jednak możesz chcieć zastąpić to zachowanie. Jeśli na przykład aplikacja wyświetla pojedynczy duży panel treści dla kanału, aplikacja może korzystać z stałej nawigacji rozszerzonych okien, ale nadal przełącza się na domyślne zachowanie klasy kompaktowej i średniej wielkości okna:

val adaptiveInfo = currentWindowAdaptiveInfo()
val customNavSuiteType = with(adaptiveInfo) {
    if (windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.EXPANDED) {
        NavigationSuiteType.NavigationDrawer
    } else {
        NavigationSuiteScaffoldDefaults.calculateFromAdaptiveInfo(adaptiveInfo)
    }
}

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

Dodatkowe materiały

Zapoznaj się ze wskazówkami dotyczącymi Material Design:

Zapoznaj się z tymi komponentami biblioteki androidx.compose.material3: