Układy kanoniczne

Układy kanoniczne to sprawdzone, uniwersalne układy, które zapewniają optymalne wrażenia użytkownikom na różnych urządzeniach.

Ilustracja urządzeń z dużym ekranem przedstawiająca układy kanoniczne.

Układy kanoniczne obsługują telefony z małymi ekranami, a także tablety, urządzenia składane i urządzenia z ChromeOS. Układy te są zgodne ze wskazówkami dotyczącymi Material Design, dzięki czemu są zarówno estetyczne, jak i funkcjonalne.

Platforma Androida zawiera specjalistyczne komponenty, które sprawiają, że wdrażanie układów jest proste i niezawodne.

Układy kanoniczne tworzą atrakcyjne interfejsy, które zwiększają produktywność i stanowią podstawę świetnych aplikacji.

Lista szczegółowa

Szkielet układu lista–szczegóły.

Układ lista–szczegóły umożliwia użytkownikom przeglądanie list elementów, które zawierają opisowe, wyjaśniające lub inne dodatkowe informacje – szczegóły elementu.

Układ dzieli okno aplikacji na 2 panele obok siebie: jeden na listę, a drugi na szczegóły. Użytkownicy wybierają elementy z listy, aby wyświetlić szczegóły produktu. Linki bezpośrednie w szczegółach ujawniają dodatkowe treści w panelu szczegółów.

Wyświetlacze o większej szerokości (patrz Korzystanie z klas rozmiaru okna) mieszczą jednocześnie listę i szczegóły. Wybranie elementu listy powoduje zaktualizowanie panelu szczegółów, który wyświetla powiązane treści.

Na wyświetlaczach o średniej i małej szerokości wyświetlana jest lista lub szczegóły w zależności od interakcji użytkownika z aplikacją. Gdy widoczna jest tylko lista, wybranie elementu listy powoduje wyświetlenie szczegółów zamiast listy. Gdy widoczne są tylko szczegóły, naciśnięcie przycisku Wstecz spowoduje ponowne wyświetlenie listy.

Zmiany konfiguracji, takie jak zmiana orientacji urządzenia lub rozmiaru okna aplikacji, mogą zmienić klasę rozmiaru okna wyświetlacza. Układ lista-szczegóły odpowiada w odpowiedni sposób, zachowując stan aplikacji:

  • Jeśli wyświetlacz o rozszerzonej szerokości, na którym widać zarówno listę, jak i okienko szczegółów, zostanie zwężony do średniej lub kompaktowej szerokości, okienko szczegółów pozostanie widoczne, a okienko listy zostanie ukryte.
  • Jeśli na ekranie o średniej lub małej szerokości widoczny jest tylko panel szczegółów, a klasa rozmiaru okna zwiększy się do rozszerzonej, lista i szczegóły będą wyświetlane razem, a na liście będzie widoczny element odpowiadający treści w panelu szczegółów.
  • Jeśli na ekranie o średniej lub małej szerokości widoczny jest tylko panel listy, a ekran zostanie rozszerzony, lista i panel szczegółów z symbolem zastępczym będą wyświetlane razem.

Wzór listy i szczegółów jest idealny w przypadku aplikacji do obsługi wiadomości, menedżerów kontaktów, interaktywnych przeglądarek multimediów i innych aplikacji, w których treść można uporządkować jako listę elementów z dodatkowymi informacjami.

Rysunek 1. Aplikacja do obsługi wiadomości z listą rozmów i szczegółami wybranej rozmowy.

Implementacja

Deklaratywny paradygmat Compose obsługuje logikę klasy rozmiaru okna, która określa, czy wyświetlać jednocześnie panele listy i szczegółów (gdy klasa rozmiaru okna o szerokości jest rozwinięta), czy tylko panel listy lub szczegółów (gdy klasa rozmiaru okna o szerokości jest średnia lub zwarta).

Aby zapewnić jednokierunkowy przepływ danych, przenieś wszystkie stany, w tym bieżącą klasę rozmiaru okna i szczegóły wybranego elementu listy (jeśli taki istnieje), tak aby wszystkie funkcje kompozycyjne miały dostęp do danych i mogły się prawidłowo renderować.

Jeśli w przypadku małych okien wyświetlany jest tylko panel szczegółów, dodaj BackHandler, aby usunąć panel szczegółów i wyświetlić tylko panel listy. Element BackHandler nie jest częścią ogólnej nawigacji aplikacji, ponieważ jego działanie zależy od klasy rozmiaru okna i wybranego stanu szczegółów.

ListDetailPaneScaffold to komponent wysokiego poziomu, który upraszcza wdrażanie układów typu szczegółowa lista. Automatycznie obsługuje logikę paneli na podstawie klas rozmiaru okna i umożliwia nawigację między panelami.

Oto minimalna implementacja z użyciem parametru ListDetailPaneScaffold:

@OptIn(ExperimentalMaterial3AdaptiveApi::class)
@Composable
fun MyListDetailPaneScaffold() {
    val navigator = rememberListDetailPaneScaffoldNavigator()
    ListDetailPaneScaffold(
        directive = navigator.scaffoldDirective,
        value = navigator.scaffoldValue,
        listPane = {
            // Listing Pane
        },
        detailPane = {
            // Details Pane
        }
    )
}

Oto kluczowe komponenty w tym przykładzie:

  • rememberListDetailPaneScaffoldNavigator: tworzy nawigatora do zarządzania nawigacją między panelami listy i szczegółów.
  • listPane: wyświetla listę produktów.
  • detailPane: wyświetla zawartość wybranego elementu.

Szczegółowe przykłady implementacji znajdziesz w tych artykułach:

Kanał

Schemat układu pliku danych.

Układ pliku danych rozmieszcza równoważne elementy treści w konfigurowalnej siatce, co umożliwia szybkie i wygodne przeglądanie dużej ilości treści.

Rozmiar i pozycja określają relacje między elementami treści.

Grupy treści tworzy się, nadając elementom ten sam rozmiar i umieszczając je obok siebie. Elementy są wyróżniane przez powiększenie ich w stosunku do sąsiednich elementów.

Karty i listy to typowe komponenty układów kanałów.

Układ pliku danych obsługuje wyświetlanie w prawie każdym rozmiarze, ponieważ siatka może się dostosowywać od pojedynczej, przewijanej kolumny do przewijanego pliku danych z wieloma kolumnami treści.

Kanały sprawdzają się szczególnie dobrze w przypadku aplikacji z wiadomościami i mediów społecznościowych.

Rysunek 2. Aplikacja społecznościowa wyświetlająca posty na kartach o różnych rozmiarach.

Implementacja

A feed consists of a large number of content elements in a vertical scrolling container laid out in a grid. Lazy lists efficiently render a large number of items in columns or rows. Lazy grids render items in grids, supporting configuration of the item sizes and spans.

Configure the columns of the grid layout based on the available display area to set the minimum allowable width for grid items. When defining grid items, adjust column spans to emphasize some items over others.

For section headers, dividers, or other items designed to occupy the full width of the feed, use maxLineSpan to take up the full width of the layout.

On compact-width displays that don't have enough space to show more than one column, LazyVerticalGrid behaves just like a LazyColumn.

Here is a minimal implementation using LazyVerticalGrid:

@Composable
fun MyFeed(names: List<String>) {
    LazyVerticalGrid(
        // GridCells.Adaptive automatically adapts column count based on available width
        columns = GridCells.Adaptive(minSize = 180.dp),
    ) {
        items(names) { name ->
            Text(name)
        }
    }
}

The key to an adaptive feed is the columns configuration. GridCells.Adaptive(minSize = 180.dp) creates a grid where each column is at least 180.dp wide. The grid then displays as many columns as can fit in the available space.

For an example implementation, see the Feed with Compose sample.

Okienko pomocnicze

Wireframe układu panelu pomocniczego.

Układ panelu pomocniczego porządkuje zawartość aplikacji na obszarach wyświetlacza głównego i dodatkowego.

Główny obszar wyświetlania zajmuje większość okna aplikacji (zwykle około dwóch trzecich) i zawiera główne treści. Dodatkowy obszar wyświetlania to panel, który zajmuje pozostałą część okna aplikacji i wyświetla treści uzupełniające główne treści.

Układy paneli pomocniczych dobrze sprawdzają się na wyświetlaczach o większej szerokości (patrz Używanie klas rozmiarów okien) w orientacji poziomej. Wyświetlacze o średniej lub małej szerokości obsługują wyświetlanie zarówno głównego, jak i dodatkowego obszaru wyświetlania, jeśli treść jest dostosowana do węższych obszarów wyświetlania lub jeśli dodatkowa treść może być początkowo ukryta w arkuszu dolnym lub bocznym, do którego można uzyskać dostęp za pomocą elementu sterującego, takiego jak menu lub przycisk.

Układ panelu pomocniczego różni się od układu lista–szczegóły relacją między treściami podstawowymi i dodatkowymi. Treści w panelu dodatkowym mają znaczenie tylko w odniesieniu do treści głównej. Na przykład okno narzędziowe panelu pomocniczego jest samo w sobie nieistotne. Treści dodatkowe w panelu szczegółów układu lista-szczegóły są jednak przydatne nawet bez treści podstawowych, np. opis produktu z listy produktów.

Przykłady zastosowań panelu pomocniczego:

Rysunek 3. Aplikacja zakupowa z opisami produktów w panelu pomocniczym.

Implementacja

Compose obsługuje logikę klas rozmiaru okna, która umożliwia określenie, czy wyświetlać jednocześnie treść główną i pomocniczą, czy umieszczać treść pomocniczą w innym miejscu.

Przenieś cały stan, w tym bieżącą klasę rozmiaru okna i informacje związane z danymi w treści głównej i pomocniczej.

W przypadku wyświetlaczy o niewielkiej szerokości umieść treści pomocnicze pod treścią główną lub w planszy dolnej. W przypadku średniej i rozszerzonej szerokości umieść treści pomocnicze obok głównych treści, odpowiednio dopasowując ich rozmiar do treści i dostępnego miejsca. W przypadku średniej szerokości podziel przestrzeń wyświetlania równo między treści główne i pomocnicze. W przypadku szerokości po rozwinięciu 70% przestrzeni powinno zajmować treść główna, a 30% – treść pomocnicza.

SupportingPaneScaffold to komponent wysokiego poziomu, który upraszcza implementację układów paneli pomocniczych. Kompozycja automatycznie obsługuje logikę paneli na podstawie klas rozmiaru okna, wyświetlając panele obok siebie na dużych ekranach lub ukrywając panel pomocniczy na małych ekranach. SupportingPaneScaffold obsługuje też przechodzenie między panelami.

Oto minimalna implementacja:

@OptIn(ExperimentalMaterial3AdaptiveApi::class)
@Composable
fun MySupportingPaneScaffold() {
    // Creates and remembers a navigator to control pane visibility and navigation
    val navigator = rememberSupportingPaneScaffoldNavigator()
    SupportingPaneScaffold(
        // Directive and value help control pane visibility based on screen size and state
        directive = navigator.scaffoldDirective,
        value = navigator.scaffoldValue,
        mainPane = {
            // Main Pane for the primary content
        },
        supportingPane = {
            //Supporting Pane for supplementary content
        }
    )
}
Kluczowe komponenty w przykładzie:

  • rememberSupportingPaneScaffoldNavigator: komponent kompozycyjny, który tworzy nawigatora do zarządzania widocznością panelu (np. ukrywania lub wyświetlania panelu pomocniczego na małych ekranach).
  • mainPane: komponent, który wyświetla główną treść.
  • supportingPane: komponent, który wyświetla treści dodatkowe;

Szczegółowe przykłady implementacji znajdziesz w tych artykułach:

Dodatkowe materiały