Elastyczne układy zapewniają optymalne wrażenia użytkowników niezależnie od rozmiaru ekranu. Wdrożyć układy elastyczne, aby umożliwić aplikacji opartej na widoku obsługę wszystkich rozmiarów, orientacji i konfiguracji wyświetlacza, w tym konfiguracji umożliwiających zmianę rozmiaru, np. tryb wielookienności.
Elastyczne projektowanie stron
Pierwszym krokiem do obsługi różnych formuł urządzeń jest utworzenie układu, który dostosowuje się do zmian w ilości miejsca na wyświetlaczu dostępnej dla aplikacji.
ConstraintLayout
Najlepszym sposobem na utworzenie układu elastycznego jest użycie ConstraintLayout
jako układu podstawowego interfejsu użytkownika. ConstraintLayout
umożliwia określenie położenia i rozmiaru każdego widoku zgodnie z relacją przestrzenną z innymi widokami w układzie. Wszystkie widoki można wtedy przesuwać i zmieniać ich rozmiary razem z przesuwającą się przestrzenią wyświetlania.
Najprostszym sposobem utworzenia układu za pomocą ConstraintLayout
jest użycie edytora układu w Android Studio. Edytor układu umożliwia przeciąganie nowych widoków do układu, stosowanie ograniczeń względem widoków nadrzędnych i podrzędnych oraz ustawianie właściwości widoku – wszystko bez ręcznej edycji kodu XML.
![](https://developer.android.google.cn/static/images/screens_support/layout-editor_2x.png?authuser=0&hl=pl)
ConstraintLayout
.
Więcej informacji znajdziesz w artykule Tworzenie elastycznego interfejsu użytkownika za pomocą ConstraintLayout.
Elastyczna szerokość i wysokość
Aby mieć pewność, że układ dostosuje się do różnych rozmiarów wyświetlacza, zamiast zakodowanych wartości użyj wartości wrap_content
, match_parent
lub 0dp (match constraint)
do szerokości i wysokości komponentów widoku:
wrap_content
: widok dostosowuje swój rozmiar do zawartości.match_parent
: widok jest rozwijany w jak największym stopniu w ramach widoku nadrzędnego.0dp (match constraint)
: w ramachConstraintLayout
, podobnie jak w przypadkumatch_parent
. Widok zajmuje całą dostępną przestrzeń w ramach swoich ograniczeń.
Przykład:
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/lorem_ipsum" />
Rysunek 4 pokazuje, jak szerokość i wysokość TextView
zmieniają się wraz ze zmianą szerokości wyświetlacza w zależności od orientacji urządzenia.
![](https://developer.android.google.cn/static/images/screens_support/layout-match-parent_2x.png?authuser=0&hl=pl)
TextView
.
Element TextView
ustawia swoją szerokość tak, aby wypełnić całą dostępną przestrzeń (match_parent
), a wysokość tak, aby dokładnie wypełnić wysokość zawartego w nim tekstu (wrap_content
). Dzięki temu widok dostosowuje się do różnych wymiarów wyświetlacza i różnych ilości tekstu.
Jeśli używasz LinearLayout
, możesz też rozwinąć widoki podrzędne na podstawie wagi układu, aby wypełniały one proporcjonalnie dostępną przestrzeń. Jednak użycie wag w zagnieżdżonym elemencie LinearLayout
wymaga od systemu wykonania kilku przejść układu w celu określenia rozmiaru każdego widoku, co spowalnia działanie interfejsu.
ConstraintLayout
może tworzyć prawie wszystkie możliwe układy za pomocą LinearLayout
bez wpływu na wydajność, dlatego przekształć osadzone elementyLinearLayout
w ConstraintLayout
. Następnie możesz zdefiniować ważone układy za pomocą łańcuchów ograniczeń.
Projektowanie adaptacyjne
Układ aplikacji powinien zawsze dostosowywać się do różnych rozmiarów wyświetlacza. Jednak nawet elastyczny układ nie zawsze zapewnia użytkownikom najlepszą wygodę na wszystkich urządzeniach lub w trybie wielookiennym. Na przykład interfejs zaprojektowany na telefon prawdopodobnie nie będzie optymalnie działać na tablecie. Projektowanie adaptacyjne umożliwia tworzenie alternatywnych układów zoptymalizowanych pod kątem różnych wymiarów wyświetlania.
SlidingPaneLayout w interfejsie użytkownika listy szczegółów
Interfejs listy z informacjami zwykle zapewnia użytkownikom różne wrażenia na ekranach o różnej wielkości. Na dużych ekranach panele listy i szczegółowych informacji są zazwyczaj umieszczone obok siebie. Po wybraniu elementu na liście informacje o nim wyświetlają się w panelu szczegółów bez zmiany interfejsu użytkownika – oba panele pozostają obok siebie. Na małych ekranach obie karty są wyświetlane osobno, a każda z nich zajmuje całą powierzchnię wyświetlacza. Po wybraniu elementu w panelu listy panel szczegółów (z informacjami o wybranym elemencie) zastępuje panel listy. Wstecz zastępuje panel szczegółów listą.
SlidingPaneLayout
zarządza logiką określania, które z 2 wersji wrażeń użytkownika jest odpowiednie dla bieżącego rozmiaru okna:
<?xml version="1.0" encoding="utf-8"?>
<androidx.slidingpanelayout.widget.SlidingPaneLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="280dp"
android:layout_height="match_parent"
android:layout_gravity="start" />
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_weight="1"
app:defaultNavHost="true"
app:navGraph="@navigation/item_navigation" />
</androidx.slidingpanelayout.widget.SlidingPaneLayout>
Atrybuty layout_width
i layout_weight
2 widoków zawartych w SlidingPaneLayout
określają zachowanie SlidingPaneLayout
. W tym przykładzie, jeśli okno jest wystarczająco duże (co najmniej 580 dp szerokości), aby wyświetlić oba widoki, panele są wyświetlane obok siebie. Jeśli jednak szerokość okna jest mniejsza niż 580 dp, panele przesuwają się po sobie, aby pojedynczo zajmować całe okno aplikacji.
Jeśli szerokość okna jest większa niż łączna minimalna szerokość (580 dp), do proporcjonalnego dopasowania rozmiaru obu paneli można użyć wartości layout_weight
. Na przykład panel listy ma zawsze szerokość 280 dp, ponieważ nie ma wagi.
Jednak panel szczegółów zawsze wypełnia całą przestrzeń poziomą poza 580 dp, ponieważ jest to ustawienie widoku layout_weight
.
Zasoby alternatywne
Aby dostosować projekt interfejsu do bardzo różnych rozmiarów ekranów, użyj alternatywnych układów zidentyfikowanych za pomocą kwalifikatorów zasobów.
![](https://developer.android.google.cn/static/images/screens_support/sizes-phone-tablet_2x.png?authuser=0&hl=pl)
Możesz udostępniać elastyczne układy dostosowane do ekranu, tworząc dodatkowe katalogi res/layout/
w kodzie źródłowym aplikacji. Utwórz katalog dla każdej konfiguracji ekranu, która wymaga innego układu. Następnie dodaj do nazwy katalogu layout
specyfikator konfiguracji ekranu (na przykład layout-w600dp
w przypadku ekranów o dostępnej szerokości 600 dp).
Kwalifikatory konfiguracji reprezentują widoczną przestrzeń wyświetlania dostępną dla interfejsu użytkownika aplikacji. Podczas wybierania układu aplikacji system bierze pod uwagę wszelkie elementy systemu (np. pasek nawigacyjny) i zmiany konfiguracji okna (np. tryb wielookienności).
Aby utworzyć alternatywne układy w Android Studio, zapoznaj się z artykułem Używanie wariantów układu do optymalizacji pod kątem różnych ekranów w artykule Tworzenie interfejsu użytkownika za pomocą Views.
Kwalifikator „najmniejsza szerokość”
Kwalifikator rozmiaru ekranu najmniejsza szerokość umożliwia udostępnianie alternatywnych układów dla wyświetlaczy o minimalnej szerokości wyrażonej w pikselach niezależnych od gęstości (dp).
Dzięki opisowi rozmiaru ekranu w jednostce dp system Android umożliwia tworzenie układów przeznaczonych do określonych wymiarów wyświetlacza bez konieczności uwzględniania różnych gęstości pikseli.
Możesz np. utworzyć układ o nazwie main_activity
zoptymalizowany pod kątem telefonów i tabletów, tworząc różne wersje pliku w różnych katalogach:
res/layout/main_activity.xml # For phones (smaller than 600dp smallest width) res/layout-sw600dp/main_activity.xml # For 7" tablets (600dp wide or wider)
Kwalifikator najmniejszej szerokości określa najmniejszą z 2 stron wyświetlacza, niezależnie od bieżącej orientacji urządzenia. Jest to sposób na określenie ogólnego rozmiaru wyświetlacza dostępnego dla układu.
Oto, jak inne wartości najmniejszej szerokości odpowiadają typomowym rozmiarom ekranu:
- 320 dp: mały ekran telefonu (240 x 320 ldpi, 320 x 480 mdpi, 480 x 800 hdpi itp.).
- 480 dp: duży ekran telefonu (480 x 800 mdpi)
- 600 dp: tablet 7" (600 x 1024 mdpi)
- 720 dp: tablet 10" (720 x 1280 mdpi, 800 x 1280 mdpi itd.)
Na rysunku poniżej widać, jak różne szerokości w pikselach odpowiadają różnym rozmiarom i orientacjom ekranu.
![](https://developer.android.google.cn/static/images/screens_support/layout-adaptive-breakpoints_2x.png?authuser=0&hl=pl)
Wartości dla klasyfikatora najmniejszy rozmiar to dp, ponieważ liczy się ilość miejsca na wyświetlaczu dostępna po uwzględnieniu przez system gęstości pikseli (a nie czystej rozdzielczości pikseli).
Rozmiary określone za pomocą kwalifikatorów zasobów, takich jak najmniejsza szerokość, nie są rzeczywistymi rozmiarami ekranu. Zamiast tego rozmiary określają szerokość lub wysokość w jednostkach dp, które są dostępne dla okna aplikacji. System Android może używać części ekranu na potrzeby interfejsu systemu (np. paska systemu u dołu ekranu lub paska stanu u góry), więc część ekranu może nie być dostępna dla układu. Jeśli aplikacja jest używana w trybie wielookiennym, ma dostęp tylko do rozmiaru okna, w którym się znajduje. Gdy rozmiar okna się zmieni, uruchamia to zmianę konfiguracji z nowym rozmiarem okna, co umożliwia systemowi wybranie odpowiedniego pliku układu. Oznacza to, że deklarowane przez Ciebie rozmiary zakwalifikowanych zasobów powinny określać tylko miejsce potrzebne Twojej aplikacji. System uwzględnia dowolną przestrzeń używaną przez interfejs użytkownika systemu, gdy udostępnia miejsce na Twój układ.
Kwalifikator dostępnej szerokości
Zamiast zmieniać układ na podstawie najmniejszej szerokości wyświetlacza, możesz zmienić go na podstawie dostępnej szerokości lub wysokości. Możesz na przykład użyć układu dwupanelowego, gdy ekran ma co najmniej 600 dp szerokości. Może się ona zmieniać w zależności od tego, czy urządzenie ma orientację poziomą czy pionową. W takim przypadku użyj kwalifikatora dostępna szerokość w ten sposób:
res/layout/main_activity.xml # For phones (smaller than 600dp available width) res/layout-w600dp/main_activity.xml # For 7" tablets or any screen with 600dp available width # (possibly landscape phones)
Jeśli dostępna wysokość jest dla Twojej aplikacji istotna, możesz użyć kwalifikatora dostępna wysokość. Na przykład layout-h600dp
w przypadku ekranów o wysokości co najmniej 600 dp.
Kwalifikatory orientacji
Chociaż możesz obsługiwać wszystkie warianty rozmiarów, korzystając tylko z kombinacji kwalifikatorów najmniejsza szerokość i dostępna szerokość, możesz też zmienić sposób wyświetlania, gdy użytkownik przełączy się między orientacją poziomą a pionową.
W tym celu możesz dodać do nazw plików w katalogu układów odpowiednie kwalifikatory: port
lub land
. Pamiętaj, aby atrybuty orientacji występowały po atrybutach rozmiaru.
Przykład:
res/layout/main_activity.xml # For phones res/layout-land/main_activity.xml # For phones in landscape res/layout-sw600dp/main_activity.xml # For 7" tablets res/layout-sw600dp-land/main_activity.xml # For 7" tablets in landscape
Więcej informacji o kwalifikatorach konfiguracji ekranu znajdziesz w artykule Omówienie zasobów aplikacji.
Klasy rozmiarów okna
Klasy rozmiarów okna to punkty przełamania widocznego obszaru, które pomagają tworzyć układy adaptacyjne. Punkty przerwania określają obszar wyświetlania dostępny dla aplikacji jako kompaktowy, średni lub rozwinięty. Szerokość i wysokość są określane osobno, więc aplikacja zawsze ma klasę rozmiaru okna dla szerokości i klasę rozmiaru okna dla wysokości.
Aby zastosować układy adaptacyjne programowo:
- tworzenie zasobów układu na podstawie punktów przecięcia klas rozmiarów okna;
- Oblicz klasy rozmiarów okna aplikacji pod względem szerokości i wysokości za pomocą funkcji
WindowSizeClass#compute()
z biblioteki Jetpack WindowManager. - Rozwijanie zasobu układu dla bieżących klas rozmiarów okna
Więcej informacji znajdziesz w artykule o rozmiarach okien.
modułowe komponenty UI korzystające z fragmentów;
Podczas projektowania aplikacji na różne rozmiary ekranu używaj fragmentów, aby wyodrębnić logikę interfejsu z osobnych komponentów. Dzięki temu nie będziesz niepotrzebnie powielać zachowania interfejsu w różnych działaniach. Następnie możesz łączyć fragmenty, aby tworzyć układy z wieloma panelami na dużych ekranach lub umieszczać fragmenty w oddzielnych aktywnościach na małych ekranach.
Na przykład wzór listy i szczegółów (patrz powyżej SlidingPaneLayout) można zaimplementować za pomocą jednego fragmentu zawierającego listę i drugiego fragmentu zawierającego szczegóły pozycji na liście. Na dużych ekranach fragmenty mogą być wyświetlane obok siebie, a na małych – pojedynczo, wypełniając cały ekran.
Więcej informacji znajdziesz w artykule o fragmentach.
Umieszczenie aktywności
Jeśli Twoja aplikacja składa się z kilku aktywności, umieszczanie aktywności umożliwia łatwe tworzenie interfejsu dostosowującego się do potrzeb użytkownika.
Przechwytywanie aktywności wyświetla w oknie zadania aplikacji kilka aktywności lub kilka wystąpień tej samej aktywności. Na dużych ekranach aktywności mogą być wyświetlane obok siebie, a na małych – jedna nad drugą.
Sposób wyświetlania aktywności przez aplikację określasz, tworząc plik konfiguracji XML, którego system używa do określenia odpowiedniej prezentacji na podstawie rozmiaru wyświetlacza. Możesz też wywoływać interfejs Jetpack WindowManager API.
Osadzanie aktywności obsługuje zmiany orientacji urządzenia i urządzenia składane, a także układanie i odkładanie aktywności podczas obracania lub składania i rozkładania urządzenia.
Więcej informacji znajdziesz w artykule Otwieranie karty Aktywność.
Rozmiary i formaty obrazu
Przetestuj aplikację na różnych rozmiarach ekranu i w różnych proporcjach, aby mieć pewność, że interfejs użytkownika skaluje się prawidłowo.
Android 10 (poziom interfejsu API 29) i nowsze wersje obsługują szeroki zakres formatów obrazu. Format składanego ekranu może się różnić od wysokich, wąskich ekranów (np. 21:9 w sposób złożonym) do kwadratowych proporcji 1:1 w sposób rozłożony.
Aby zapewnić zgodność z jak największą liczbą urządzeń, przetestuj aplikacje w jak największej liczbie tych formatów obrazu:
![](https://developer.android.google.cn/static/images/guide/topics/ui/foldables/fold-screen-ratios.png?authuser=0&hl=pl)
Jeśli nie masz dostępu do urządzeń o różnych rozmiarach ekranu, które chcesz przetestować, możesz użyć Emulatora Androida, aby emulować niemal każdy rozmiar ekranu.
Jeśli wolisz testować na prawdziwym urządzeniu, ale go nie masz, możesz skorzystać z Laboratorium Firebase, aby uzyskać dostęp do urządzeń w centrum danych Google.
Dodatkowe materiały
- Material Design – zapoznanie się z układem