Migracja interfejsu do układów elastycznych

Aplikacje na Androida muszą obsługiwać stale rozwijający się ekosystem formatów urządzeń. Interfejs aplikacji powinien być elastyczny, aby pasować do różnych rozmiarów ekranów, a także różnych orientacji i stanów urządzenia.

Elastyczny interfejs bazuje na zasadach elastyczności i ciągłości.

Elastyczność oznacza układy, które optymalnie wykorzystują dostępną przestrzeń i dostosowują ją, gdy się zmienia. Korekty mogą przyjmować różne formy: zwiększać rozmiar pojedynczego widoku, zmieniać pozycję widoków tak, aby były dostępne w bardziej dostępnych miejscach, wyświetlać lub ukrywać dodatkowe widoki, a także łączyć te elementy.

Ciągłość oznacza płynną obsługę podczas przechodzenia z jednego rozmiaru okna do drugiego. Niezależnie od tego, co korzysta z niej użytkownik, powinno być aktywne bez zakłóceń. Przyczyną zmiany rozmiaru może być zniszczenie i odtworzenie całej hierarchii widoków, dlatego ważne jest, aby użytkownik nie utracił swojego miejsca ani danych.

Czego unikać

Unikaj używania fizycznych wartości sprzętowych przy podejmowaniu decyzji dotyczących układu. Podejmowanie decyzji na podstawie ustalonej wartości może być kuszące, ale w wielu przypadkach nie są one przydatne do określenia ilości miejsca, w jakim może działać interfejs użytkownika.

W aplikacjach w trybie wielu okien, obrazie w obrazie lub w oknach dowolnych (np. ChromeOS) mogą występować zmiany rozmiaru okien. Może być nawet więcej niż jeden fizyczny ekran, na przykład urządzenie składane lub urządzenie z kilkoma wyświetlaczami. We wszystkich tych przypadkach rozmiar ekranu nie ma wpływu na decydowanie o sposobie wyświetlania treści.

Kilka urządzeń z oknami aplikacji w różnych rozmiarach.
Rysunek 1. Rozmiary okien mogą różnić się od rozmiaru ekranu urządzenia lub wyświetlacza.

Z tego samego powodu unikaj blokowania aplikacji w określonej orientacji lub formacie obrazu. Choć samo urządzenie może mieć określoną orientację, aplikacja może mieć inną orientację tylko ze względu na rozmiar okna. Na przykład na tablecie w orientacji poziomej w trybie wielu okien aplikacja może być pionowa, ponieważ jest wyższa niż szersza.

Unikaj też sprawdzania, czy urządzenie to telefon czy tablet. To, co zalicza się do tabletów, jest subiektywne: czy zależy od konkretnego rozmiaru, współczynnika proporcji lub połączenia rozmiaru i współczynnika proporcji? W miarę pojawiania się nowych formatów te założenia mogą się zmieniać, a różnice przestają być ważne.

Zamiast wypróbować którąkolwiek z poprzednich strategii, używaj punktów przerwania i klas rozmiaru okna.

Punkty przerwania i klasy rozmiaru okna

Odpowiedni fragment ekranu przypisany do aplikacji to okno aplikacji. Może zajmować cały ekran lub jego część, dlatego przy podejmowaniu ogólnych decyzji o układzie aplikacji używaj rozmiaru okna.

Podczas projektowania pod kątem wielu formatów znajdź wartości progowe, w których te ogólne decyzje rozchodzą się w różnych kierunkach. W tym celu siatka układu elastycznego Material Design zapewnia punkty przerwania szerokości i wysokości, co pozwala mapować nieprzetworzone rozmiary na dyskretne, ustandaryzowane grupy nazywane klasami rozmiaru okna. Ze względu na powszechność przewijania w pionie większość aplikacji zwraca przede wszystkim uwagę na klasy rozmiaru ekranu. W przypadku większości aplikacji można więc zoptymalizować aplikację pod kątem wszystkich rozmiarów ekranu przez obsługę tylko kilku punktów przerwania. Więcej informacji o klasach rozmiaru okna znajdziesz w artykule Klasy rozmiaru okna.

Stałe elementy interfejsu użytkownika

Wskazówki dotyczące układu Material Design określają regiony dla pasków aplikacji, nawigacji i treści. Zazwyczaj 2 pierwsze elementy to trwałe elementy interfejsu u głównego poziomu hierarchii widoków (lub bardzo blisko niego). Pamiętaj, że „trwały” nie musi oznaczać, że widok jest zawsze widoczny, ale że pozostaje na swoim miejscu, gdy inne wyświetlenia treści mogą się przesunąć lub zmienić. Na przykład element nawigacji może znajdować się w przesuwanej szufladzie, która jest poza ekranem, ale szuflada jest zawsze widoczna.

Trwałe elementy mogą być elastyczne i zwykle zajmują pełną szerokość lub wysokość okna, dlatego zalecamy używanie klas rozmiaru, aby zdecydować, gdzie je umieścić. Określa miejsce pozostawione na treści. W tym fragmencie kodu aktywność używa dolnego paska na kompaktowych ekranach i górnego paska aplikacji w przypadku większych ekranów. Zakwalifikowany układ używa punktów przerwania szerokości w opisany wcześniej sposób.

<!-- res/layout/main_activity.xml -->

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- content view(s) -->

    <com.google.android.material.bottomappbar.BottomAppBar
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        ... />
</androidx.constraintlayout.widget.ConstraintLayout>


<!-- res/layout-w600dp/main_activity.xml -->
<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        ... />

    <!-- content view(s) -->
</androidx.constraintlayout.widget.ConstraintLayout>

Treści

Po rozmieszczeniu trwałych elementów interfejsu wykorzystaj pozostałą część miejsca na treść, np. użyj NavHostFragment z wykresem nawigacyjnym aplikacji. Dodatkowe informacje znajdziesz w artykule Nawigacja po elastycznych interfejsach.

Sprawdź, czy wszystkie dane są dostępne dla różnych rozmiarów

Większość platform aplikacji korzysta obecnie z modelu danych oddzielonego od komponentów Androida, które stanowią element interfejsu użytkownika (aktywności, fragmentów i widoków). W Jetpack tę rolę zwykle pełnią modele ViewModels, które mają dodatkową zaletę polegającą na niezmienianiu konfiguracji (więcej informacji znajdziesz w artykule ViewModel Overview).

Podczas wdrażania układu, który dostosowuje się do różnych rozmiarów, kuszące może być użycie innego modelu danych w zależności od bieżącego rozmiaru. Jest to jednak sprzeczne z zasadą jednokierunkowego przepływu danych. Dane powinny przechodzić w dół do wyświetleń, a zdarzenia takie jak interakcje użytkowników – rosną. Utworzenie zależności w drugim kierunku, w której model danych jest zależny od konfiguracji warstwy interfejsu, znacznie je komplikuje. Gdy aplikacja zmieni rozmiar, musisz uwzględnić konwersję z jednego modelu danych na inny.

Zamiast tego pozwól modelowi danych uwzględnić największą klasę rozmiaru, a następnie będziesz mieć możliwość selektywnego wyświetlania, ukrywania lub zmiany pozycji treści w interfejsie, aby dostosować się do bieżącej klasy rozmiaru. Poniżej znajdziesz kilka strategii, których możesz użyć przy podejmowaniu decyzji o tym, jak układ powinien zachowywać się podczas przechodzenia między klasami rozmiaru.

Rozwiń treść

Układy kanoniczne: kanał

Większa przestrzeń to szansa na po prostu większy rozmiar i zmianę formatu treści, aby były bardziej dostępne.

Powiększanie kolekcji. Wiele aplikacji wyświetla w kontenerze przewijanym kolekcję elementów, np. RecyclerView lub ScrollView. Włączenie automatycznego powiększenia kontenera oznacza, że można wyświetlić więcej treści. Uważaj jednak, aby zawartość kontenera nie była nadmiernie rozciągnięta lub zniekształcona. W przypadku elementu RecyclerView rozważ na przykład użycie innego menedżera układu, takiego jak GridLayoutManager, StaggeredGridLayoutManager lub FlexboxLayout, gdy szerokość nie jest kompaktowa.

Rozłożone i rozłożone urządzenie, na którym widać, jak różni menedżerowie układu układają aplikację w zależności od klasy rozmiaru.
Rysunek 2. Różni menedżerowie układu dla różnych klas rozmiarów okien.

Poszczególne elementy mogą też mieć różne rozmiary lub kształty, aby wyświetlać więcej treści i łatwiej odróżniać granice elementów.

Wyróżnij główny element. Jeśli układ ma określony główny element, np. obraz lub film, rozwiń go wraz z powiększaniem się okna aplikacji, aby utrzymać uwagę użytkownika. Inne elementy dodatkowe można rozmieścić wokół lub pod widokiem banera powitalnego.

Istnieje wiele sposobów na stworzenie takiego układu, ale element ConstraintLayout szczególnie nadaje się do tego celu, ponieważ umożliwia ograniczenie rozmiaru widoku podrzędnego – w tym za pomocą wartości procentowych lub wymuszanie określonego współczynnika proporcji – oraz pozycjonowanie elementów podrzędnych względem siebie lub innych elementów podrzędnych. Więcej informacji o wszystkich tych funkcjach znajdziesz w artykule Tworzenie elastycznego interfejsu z użyciem ConstraintLayout.

Domyślnie pokazuj zawartość zwijaną. Gdy tylko jest dość miejsca, zaproponuj treści, które w innym przypadku byłyby dostępne wyłącznie w ramach dodatkowej interakcji z użytkownikiem, np. dotykania, przewijania lub gestów. Dotyczy to na przykład treści, które pojawiają się w interfejsie z kartami, gdy zamiast kompaktowej kompaktowej treści brakuje miejsca na kolumny lub listę, gdy dostępne jest więcej miejsca.

Zwiększ marże. Jeśli przestrzeń jest tak duża, że nawet po wykorzystaniu wszystkich treści nie można znaleźć odpowiedniego dopasowania, zwiększ marginesy układu, aby treści były wyśrodkowane, a poszczególne widoki miały naturalne rozmiary i odstępy między nimi.

Innym sposobem jest przekształcenie komponentu pełnoekranowego w pływający interfejs okien dialogowych. Jest to szczególnie przydatne, gdy komponent wymaga skupienia się wyłącznie na wykonywaniu natychmiastowego zadania użytkownika, np. pisaniu e-maila lub wydarzeniu w kalendarzu.

Standardowy telefon z oknem na pełnym ekranie i rozłożonym składanym telefonem z tym samym oknem co pływające okno.
Rysunek 3. Okno pełnoekranowe przekształcone w standardowe okno o średniej i rozwiniętej szerokości.

Dodaj treść

Układy kanoniczne: dodatkowy panel, widok szczegółów listy

Skorzystaj z panelu uzupełniającego. W panelu pomocniczym znajdują się dodatkowe treści lub działania kontekstowe związane z treścią główną, np. komentarze w dokumencie czy elementy na playliście. Zazwyczaj wykorzystuje się one w dolnej trzeciej części ekranu, by zwiększyć wysokość, lub w końcowej trzeciej, by zwiększyć szerokość.

Ważne jest, aby umieścić te treści, gdy nie ma wystarczającej ilości miejsca na wyświetlenie panelu. Oto kilka innych możliwości:

  • Boczna szuflada na końcowej krawędzi za pomocą funkcji DrawerLayout
  • Dolna szuflada używa funkcji BottomSheetBehavior
  • Menu lub wyskakujące okienko można otworzyć po kliknięciu ikony menu
Rysunek 4. Alternatywne sposoby prezentowania dodatkowych treści w panelu pomocniczym.

Tworzenie układu z 2 panelami. Na dużych ekranach może być wyświetlana kombinacja funkcji, które normalnie są wyświetlane oddzielnie na mniejszych ekranach. Częstym wzorcem interakcji w wielu aplikacjach jest wyświetlanie listy elementów, na przykład kontaktów lub wyników wyszukiwania, i przełączanie się do szczegółów elementu po jego wybraniu. Zamiast powiększać listę na większe ekrany, użyj widoku szczegółów, aby wyświetlić obie funkcje obok siebie w układzie z 2 panelami. W przeciwieństwie do obsługiwanego panelu okienko szczegółów w widoku szczegółów jest samodzielnym elementem, który można wyświetlać niezależnie na mniejszych ekranach.

Użyj specjalnego widżetu SlidingPaneLayout do implementacji widoku szczegółów listy. Ten widżet automatycznie oblicza, czy wystarczy wystarczająco dużo miejsca na wyświetlenie obu paneli razem, na podstawie wartości layout_width określonej dla dwóch paneli, a wolne miejsce może być rozkładane za pomocą funkcji layout_weight. Gdy brakuje miejsca, każdy panel wykorzystuje pełną szerokość układu, a okienko szczegółów przesuwa się poza ekran lub nad nim.

SlidingPaneLayout pokazujący oba panele układu z szczegółami listy na urządzeniu z szerokim ekranem.
Rysunek 5. SlidingPaneLayout pokazujący 2 panele w szerokości rozwiniętej i 1 o kompaktowej szerokości.

Artykuł Tworzenie układu z 2 panelami zawiera więcej informacji o korzystaniu z SlidingPaneLayout. Pamiętaj też, że ten wzorzec może mieć wpływ na strukturę wykresu nawigacyjnego (patrz Nawigacja po elastycznych interfejsach).

Dodatkowe materiały