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.

Szczegółowa lista

Schemat strony szczegółowej listy.

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 widoku szczegółowym 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, tak aby 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 lista-szczegóły idealnie sprawdza się 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 listę i okienko szczegółów (gdy klasa rozmiaru okna jest rozszerzona), czy tylko listę lub okienko szczegółów (gdy klasa rozmiaru okna jest średnia lub kompaktowa).

Aby zapewnić jednokierunkowy przepływ danych, podnieś cały stan, w tym bieżącą klasę rozmiaru okna i szczegóły wybranego elementu listy (jeśli występują), tak aby wszystkie elementy kompozycyjne miały dostęp do danych i mogły je prawidłowo renderować.

Jeśli w małym oknie wyświetla się tylko okienko szczegółów, dodaj BackHandler, aby usunąć okienko szczegółów i wyświetlić tylko okienko listy. BackHandler nie jest częścią ogólnej nawigacji w aplikacji, ponieważ moduł obsługi zależy od klasy rozmiaru okna i wybranego stanu szczegółów.

ListDetailPaneScaffold to funkcja kompozycyjna wysokiego poziomu, która upraszcza implementację układów szczegółowych list. Automatycznie obsługuje logikę paneli na podstawie klas rozmiarów okien i obsługuje nawigację między panelami.

Oto minimalna implementacja z użyciem 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 nawigator do zarządzania nawigacją między listą a okienkiem szczegółów.
  • listPane: wyświetla listę elementó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

Kanał składa się z dużej liczby elementów treści w kontenerze przewijanym w pionie, które są ułożone w siatkę. Leniwe listy skutecznie renderują dużą liczbę elementów w kolumnach lub wierszach. Siatki Lazy renderują elementy w siatkach, obsługując konfigurację rozmiarów i rozpiętości elementów.

Skonfiguruj kolumny układu siatki na podstawie dostępnego obszaru wyświetlania, aby ustawić minimalną dopuszczalną szerokość elementów siatki. Podczas definiowania elementów siatki dostosuj rozpiętość kolumn, aby wyróżnić niektóre elementy.

W przypadku nagłówków sekcji, separatorów lub innych elementów, które mają zajmować całą szerokość kanału, użyj maxLineSpan, aby zajmowały całą szerokość układu.

Na wyświetlaczach o szerokości kompaktowej, na których nie ma wystarczająco dużo miejsca, aby wyświetlić więcej niż 1 kolumnę, LazyVerticalGrid zachowuje się tak samo jak LazyColumn.

Oto minimalna implementacja z użyciem 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)
        }
    }
}

Kluczem do adaptacyjnego kanału jest konfiguracja columns. GridCells.Adaptive(minSize = 180.dp) tworzy siatkę, w której każda kolumna ma szerokość co najmniej 180.dp. Siatka wyświetla wtedy tyle kolumn, ile mieści się w dostępnym miejscu.

Przykładową implementację znajdziesz w przykładzie kanału z Compose.

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ść można dostosować do węższych obszarów wyświetlania lub jeśli dodatkową treść można początkowo ukryć 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 zastosowania panelu pomocniczego:

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

Implementacja

Compose obsługuje logikę klasy rozmiaru okna, która pozwala określić, czy wyświetlać jednocześnie zarówno treść główną, jak i treść pomocniczą, czy też umieścić treść pomocniczą w innym miejscu.

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

W przypadku wyświetlaczy o szerokości kompaktowej umieść treści pomocnicze pod treściami głównymi lub na planszy dolnej. W przypadku średnich szerokości i szerokości po rozwinięciu umieść treści pomocnicze obok treści głównych, dostosowując ich rozmiar do treści i dostępnego miejsca. W przypadku średniej szerokości podziel przestrzeń wyświetlania po równo między treści główne i pomocnicze. W przypadku szerokości po rozwinięciu przeznacz 70% miejsca na główną treść, a 30% na treść pomocniczą.

SupportingPaneScaffold to funkcja kompozycyjna wysokiego poziomu, która upraszcza implementację układów paneli pomocniczych. Funkcja kompozycyjna 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ż nawigację 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: funkcja kompozycyjna, która tworzy nawigator do zarządzania widocznością panelu (np. ukrywanie lub wyświetlanie panelu pomocniczego na ekranach kompaktowych).
  • mainPane: funkcja kompozycyjna, która wyświetla główną treść.
  • supportingPane: element kompozycyjny, który wyświetla treści dodatkowe.

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

Dodatkowe materiały