Utwórz elastyczny interfejs użytkownika z wykorzystaniem ConstraintUkład Część stanowiąca część Androida Jetpack.
ConstraintLayout
pozwala tworzyć duże, złożone układy z użyciem płaskiej hierarchii widoków – bez zagnieżdżonych grup widoków. Podobnie jak w przypadku RelativeLayout
, wszystkie widoki są rozmieszczone na podstawie relacji między widokami równorzędnymi a układem nadrzędnym. Jest on jednak bardziej elastyczny niż tryb RelativeLayout
i łatwiejszy w użyciu z edytorem układów w Android Studio.
Wszystkie możliwości usługi ConstraintLayout
są dostępne bezpośrednio w narzędziach wizualnych edytora układu, ponieważ interfejs API układu i edytor układu są do siebie opracowane. Możesz utworzyć układ za pomocą ConstraintLayout
w całości, przeciągając go, zamiast edytować plik XML.
Na tej stronie dowiesz się, jak utworzyć układ za pomocą ConstraintLayout
w Android Studio w wersji 3.0 lub nowszej. Więcej informacji o edytorze układu znajdziesz w artykule Tworzenie interfejsu przy użyciu edytora układu.
Różne układy, które można tworzyć za pomocą ConstraintLayout
, znajdziesz w projekcie Przykładowych układów ograniczeń na GitHubie.
Omówienie ograniczeń
Aby określić położenie widoku w polu ConstraintLayout
, dodaj do niego co najmniej jedno ograniczenie poziome i jedno pionowe. Każde ograniczenie reprezentuje połączenie lub wyrównanie z innym widokiem, układ nadrzędny lub niewidoczną wskazówkę. Każde ograniczenie określa pozycję widoku wzdłuż osi pionowej lub poziomej. Każdy widok musi mieć co najmniej 1 ograniczenie na każdą oś, ale często potrzeba więcej.
Upuść widok w edytorze układu, aby go opuścić, nawet jeśli nie ma żadnych ograniczeń. Ma to jedynie ułatwić edytowanie. Jeśli widok nie ma ograniczeń po uruchomieniu układu na urządzeniu, jest on rysowany w pozycji [0,0] (w lewym górnym rogu).
Na ilustracji 1 układ wygląda dobrze w edytorze, ale nie ma w widoku C ograniczeń pionowych. Gdy ten układ jest rysowany na urządzeniu, widok C w poziomie jest dopasowywany do lewej i prawej krawędzi widoku A, ale pojawia się u góry ekranu, ponieważ nie ma blokady w pionie.
Brakujące ograniczenie nie powoduje błędu kompilacji, ale Edytor układu wskazuje brakujące ograniczenia jako błąd na pasku narzędzi. Aby wyświetlić błędy i inne ostrzeżenia, kliknij Pokaż ostrzeżenia i błędy . Aby ułatwić Ci uniknięcie brakujących ograniczeń, edytor układu automatycznie dodaje ograniczenia w ramach funkcji Automatyczne łączenie i określanie ograniczeń.
Dodaj układ ograniczeń do projektu
Aby użyć usługi ConstraintLayout
w projekcie, wykonaj te czynności:
- Sprawdź, czy w pliku
settings.gradle
zadeklarowano repozytoriummaven.google.com
:Odlotowy
dependencyResolutionManagement { ... repositories { google() } )
Kotlin
dependencyResolutionManagement { ... repositories { google() } }
- Dodaj bibliotekę jako zależność w pliku
build.gradle
na poziomie modułu, jak pokazano w poniższym przykładzie. Najnowsza wersja może się różnić od pokazanej w przykładzie.Odlotowy
dependencies { implementation "androidx.constraintlayout:constraintlayout:2.2.0-alpha13" // To use constraintlayout in compose implementation "androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha13" }
Kotlin
dependencies { implementation("androidx.constraintlayout:constraintlayout:2.2.0-alpha13") // To use constraintlayout in compose implementation("androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha13") }
- Na pasku narzędzi lub w powiadomieniu o synchronizacji kliknij Synchronizuj projekt z plikami Gradle.
Teraz możesz utworzyć układ w usłudze ConstraintLayout
.
Konwertowanie układu
Aby przekonwertować istniejący układ na układ z ograniczeniami, wykonaj te czynności:
- Otwórz układ w Android Studio i kliknij kartę Projekt u dołu okna edytora.
- W oknie Drzewo komponentów kliknij układ prawym przyciskiem myszy i wybierz Przekonwertuj układ liniowy na układ ograniczeń.
Tworzenie nowego układu
Aby utworzyć nowy plik układu ograniczeń, wykonaj te czynności:
- W oknie Projekt kliknij folder modułu i wybierz Plik > Nowy > XML > XML układu.
- Wpisz nazwę pliku układu i w polu Tag główny wpisz „androidx.constraintlayout.Widget.ConstraintLayout”.
- Kliknij Zakończ.
Dodawanie lub usuwanie ograniczenia
Aby dodać ograniczenie:
Przeciągnij widok z okna Paleta do edytora.
Gdy dodasz widok do obiektu
ConstraintLayout
, będzie on wyświetlany w ramce ograniczającej z kwadratowymi uchwytami zmiany rozmiaru po każdym narożniku i okrągłymi uchwytami ograniczeń po każdej stronie.- Kliknij widok, aby go wybrać.
- Wykonaj jedną z tych czynności:
- Kliknij uchwyt ograniczenia i przeciągnij go do dostępnego punktu zakotwiczenia. Może to być krawędź innego widoku, krawędzi układu lub wskazówki. Zwróć uwagę, że podczas przeciągania uchwytu ograniczenia edytor układu wyświetla potencjalne kotwice połączeń i niebieskie nakładki.
Kliknij jeden z przycisków Utwórz połączenie w sekcji Układ w oknie Atrybuty, jak pokazano na rysunku 4.
Po utworzeniu ograniczenia edytor przypisuje mu domyślny margines, który rozdziela te 2 widoki.
Podczas tworzenia ograniczeń pamiętaj o tych regułach:
- Każdy widok musi mieć co najmniej 2 ograniczenia: jedno poziome i jedno pionowe.
- Ograniczenia można tworzyć tylko między uchwytem ograniczenia a punktem zakotwiczenia, które korzystają z tej samej płaszczyzny. Płaszczyzna pionowa – lewą i prawą stronę – może zostać ograniczona tylko do innej płaszczyzny pionowej, a linie bazowe mogą się ograniczać tylko do innych punktów odniesienia.
- Każdy uchwyt ograniczenia może służyć tylko do 1 ograniczenia, ale można utworzyć wiele ograniczeń dla tego samego punktu zakotwiczenia w różnych widokach.
Ograniczenie możesz usunąć, wykonując jedną z tych czynności:
- Kliknij ograniczenie, aby je wybrać, a następnie kliknij Usuń.
Przytrzymaj Control (przytrzymaj Command w systemie macOS) i kliknij kotwicę ograniczenia. Ograniczenie zmieni kolor na czerwony, aby wskazać, że możesz je usunąć kliknięciem, jak pokazano na ilustracji 5.
W sekcji Układ w oknie Atrybuty kliknij kotwicę ograniczenia, tak jak na ilustracji 6.
Jeśli dodasz przeciwne od siebie blokady w widoku, te linie zwijają się jak sprężyna, by wskazać przeciwne siły, jak widać na filmie 2. Efekt jest najbardziej widoczny, gdy rozmiar widoku jest ustawiony na „stałe” lub „zawijanie treści”. W takim przypadku widok jest wyśrodkowany między ograniczeniami. Jeśli chcesz, by widok rozciągał się zgodnie z ograniczeniami, zmień rozmiar na „pasuj z ograniczeniami”. Jeśli chcesz zachować bieżący rozmiar, ale przesunąć widok tak, aby nie był wyśrodkowany, dostosuj odchylenie ograniczenia.
Za pomocą ograniczeń możesz uzyskać różne typy działania układu, zgodnie z opisem w sekcjach poniżej.
Pozycja nadrzędna
Ogranicz bok widoku do odpowiedniej krawędzi układu.
Na rys. 7 lewa strona widoku jest połączona z lewą krawędzią układu nadrzędnego. Możesz określić odległość od krawędzi z marginesami.
Pozycja zamówienia
Zdefiniuj kolejność wyświetlania dwóch widoków – pionowo lub poziomo.
Na ilustracji 8 obiekt B musi zawsze znajdować się po prawej stronie od A, a cel C jest ograniczony poniżej punktu A. Te ograniczenia nie oznaczają jednak wyrównania, więc B może nadal poruszać się w górę i w dół.
Wyrównanie
Dopasowywanie krawędzi jednego widoku do tej samej krawędzi innego widoku.
Na rys. 9 lewa strona litery B jest wyrównana do lewej strony punktu A. Jeśli chcesz wyrównać środki widoku, utwórz ograniczenie po obu stronach.
Możesz przesunąć wyrównanie, przeciągając widok do wewnątrz. Na przykład na ilustracji 10 widać obraz B z wyrównaniem z przesunięciem o 24 dp. Przesunięcie jest określane przez margines ograniczonego widoku.
Możesz też wybrać wszystkie widoki, które chcesz wyrównać, a następnie kliknąć Wyrównaj na pasku narzędzi, aby wybrać typ wyrównania.
Wyrównanie punktu odniesienia
Wyrównaj tekst bazowy widoku z bazą tekstu innego widoku.
Na ilustracji 11 pierwszy wiersz wiersza B jest wyrównany z tekstem w kolekcji A.
Aby utworzyć ograniczenie bazowe, kliknij prawym przyciskiem myszy widok tekstu, który chcesz ograniczyć, a następnie kliknij Pokaż linię bazową. Następnie kliknij linię bazową tekstu i przeciągnij ją do innej linii bazowej.
Ogranicz do wytycznych
Możesz dodać pionową lub poziomą wskazówkę, która pozwoli ograniczyć widoki i będzie niewidoczna dla użytkowników aplikacji. Możesz umieścić wskazówkę w układzie na podstawie jednostek dp lub wartości procentowej względem krawędzi układu.
Aby utworzyć wskazówkę, kliknij Wskazówki na pasku narzędzi, a następnie kliknij Dodaj wskazówkę pionową lub Dodaj wytyczną poziomą.
Przeciągnij przerywaną linię, aby zmienić jej położenie. Kliknij okrąg przy krawędzi, aby przełączyć tryb pomiaru.
Ograniczenie do bariery
Podobnie jak w przypadku wytycznych, bariera to niewidoczna linia, do której możesz ograniczać widoki. Jedyna różnica polega na tym, że bariera nie definiuje własnego położenia. Zamiast tego pozycja bariery zmienia się w zależności od położenia zawartych w niej widoków. Jest to przydatne, gdy chcesz ograniczyć widok do zestawu, a nie do jednego konkretnego widoku.
Na przykład na rys. 13 widok C jest ograniczony po prawej stronie bariery. Barierę znajduje się po „końcu” (lub po prawej stronie w układzie od lewej do prawej) zarówno w widoku A, jak i w widoku B. Bariera zmienia się w zależności od tego, czy jest najdalej od prawej strony widoku A, czy B.
Aby utworzyć barierę, wykonaj te czynności:
- Kliknij Guidelines na pasku narzędzi, a następnie Add Vertical Barrier (Dodaj barierę pionową) lub Add Horizontal Barrier (Dodaj barierę pionową).
- W oknie Drzewo komponentów wybierz widoki wewnątrz bariery i przeciągnij je do komponentu bariery.
- Wybierz barierę w drzewie komponentów, otwórz okno Atrybuty i ustaw barrierDirection.
Teraz możesz utworzyć ograniczenie z innego widoku.
Możesz też ograniczyć widoki, które znajdują się wewnątrz bariery. W ten sposób możesz wyrównać ze sobą wszystkie widoki w przeszkodzie, nawet jeśli nie wiesz, który z nich jest najdłuższy, a który najwyższy.
Możesz też umieścić w barierce wskazówkę, aby zapewnić minimalną długość bariery.
Dostosuj odchylenie ograniczenia
Gdy dodasz ograniczenie po obu stronach widoku, a rozmiar widoku dla tego samego wymiaru będzie mieć wartość „stały” lub „zawijaj treść”, widok zostanie wyśrodkowany między 2 ograniczeniami z odchyleniem na poziomie 50%. Możesz dostosować odchylenie, przeciągając suwak odchylenia w oknie Atrybuty lub przeciągając widok, tak jak pokazano na filmie 3.
Jeśli chcesz, by widok rozciągał się zgodnie z ograniczeniami, zmień rozmiar na „pasuj z ograniczeniami”.
Dostosowywanie rozmiaru widoku
Za pomocą narożników możesz zmienić rozmiar widoku, ale wtedy ten rozmiar jest zakodowany na stałe – rozmiar widoku nie zmienia się w zależności od zawartości lub rozmiaru ekranu. Aby wybrać inny tryb rozmiaru, kliknij widok i otwórz okno Atrybuty po prawej stronie edytora.
W górnej części okna Atrybuty znajduje się inspektor widoku, który zawiera elementy sterujące kilkoma atrybutami układu, jak widać na ilustracji 14. Ta opcja jest dostępna tylko w przypadku widoków w układzie z ograniczeniami.
Sposób obliczania wysokości i szerokości możesz zmienić, klikając symbol objaśnienia 3 na rys. 14. Symbole oznaczają tryb rozmiaru w ten sposób. Kliknij ten symbol, aby przełączać się między tymi ustawieniami:
- Stałe: określ konkretny wymiar w poniższym polu tekstowym lub zmień rozmiar widoku w edytorze.
- Zawijaj zawartość: widok rozwija się tylko tak bardzo, jak to konieczne, by pasował do jego zawartości.
- layout_restrictedWidth
-
Ograniczenia dopasowania: po uwzględnieniu marginesów danego widoku widok jest maksymalnie rozwijany, aby spełnić ograniczenia po każdej stronie. Możesz jednak zmodyfikować to działanie za pomocą poniższych atrybutów i wartości. Te atrybuty obowiązują tylko wtedy, gdy ustawisz szerokość widoku na „dopasuj ograniczenia”:
- layout_constraintWidth_min
Przyjmuje to wymiar
dp
odpowiadający minimalnej szerokości widoku. - layout_constraintWidth_max,
Wymaga to użycia
dp
wymiaru dla maksymalnej szerokości widoku.
Jeśli jednak dany wymiar ma tylko jedno ograniczenie, widok rozwija się zgodnie ze swoją zawartością. Korzystanie z tego trybu do określania wysokości lub szerokości umożliwia też ustawienie współczynnika rozmiaru.
- layout_constraintWidth_min
Ustaw wartość true
, aby umożliwić zmianę wymiaru poziomego zgodnie z ograniczeniami. Domyślnie widżet ustawiony na WRAP_CONTENT
nie jest ograniczony przez ograniczenia.
Ustaw rozmiar jako współczynnik
Jeśli co najmniej jeden z wymiarów widoku ma wartość „ograniczenia dopasowania” (0dp
), możesz ustawić jego współczynnik proporcji, np. 16:9. Aby go włączyć, kliknij Przełącz ograniczenie współczynnika proporcji (objaśnienie 1 na ilustracji 14) i w wyświetlonym polu wpisz współczynnik width:height.
Jeśli zarówno szerokość, jak i wysokość są ustawione na „ograniczenia dopasowania”, możesz kliknąć Przełącz ograniczenie współczynnika proporcji, aby wybrać, który wymiar ma być oparty na współczynniku proporcji drugiego. Inspektor widoku wskazuje, który wymiar ma być ustawiony jako współczynnik, łącząc odpowiadające sobie krawędzie linią ciągłą.
Jeśli na przykład dla obu stron ustawisz „ograniczenia dopasowania”, kliknij dwukrotnie ograniczenie współczynnika proporcji, aby ustawić szerokość jako współczynnik wysokości. Cały rozmiar jest uzależniony od wysokości widoku, który można w dowolny sposób zdefiniować, tak jak na rys. 15.
Dostosowywanie marginesów widoku
Aby ustawić równomierne odstępy między widokami, kliknij Marża na pasku narzędzi i wybierz domyślny margines dla każdego widoku, który dodasz do układu. Wszelkie zmiany, jakie wprowadzisz do marginesu domyślnego, będą dotyczyć tylko widoków, które dodasz od tego momentu.
Margines każdego widoku możesz ustawić w oknie Atrybuty, klikając liczbę w wierszu reprezentującym każde ograniczenie. Na ilustracji 14 wywołanie 4 pokazuje, że dolny margines jest ustawiony na 16 dp.
Wszystkie marże oferowane przez narzędzie to 8 dp. Dzięki temu wyświetlane widoki są zgodne z zaleceniami siatki kwadratowej 8 dp w interfejsie Material Design.
Sterowanie grupami liniowymi za pomocą łańcucha
Łańcuch to grupa widoków połączonych ze sobą za pomocą dwukierunkowych ograniczeń pozycji. Widoki w łańcuchu mogą być rozłożone w pionie lub w poziomie.
Można określić styl łańcuchów na jeden z tych sposobów:
- Rozłożone: wyświetlenia są równomiernie rozłożone po uwzględnieniu marż. Jest to ustawienie domyślne.
- Rozpowszechnij w środku: pierwszy i ostatni widok są przymocowane do ograniczeń na każdym końcu łańcucha, a pozostałe są równomiernie rozłożone.
- Ważona: gdy łańcuch jest ustawiony na spread lub spread w środku, możesz wypełnić pozostałe miejsce, ustawiając „ograniczenia dopasowania” w co najmniej jednym widoku (
0dp
). Domyślnie przestrzeń jest równomiernie rozłożona między każdy widok z ustawionymi „ograniczeniami dopasowania”, ale możesz przypisać wagę do każdego widoku, korzystając z atrybutówlayout_constraintHorizontal_weight
ilayout_constraintVertical_weight
. Działa to tak samo jak w przypadku właściwościlayout_weight
w układzie liniowym: widok o największej wartości wagi zajmuje najwięcej miejsca, a widoki o tej samej wadze zajmują tyle samo miejsca. - Spakowane: wyświetlenia są sumowane po uwzględnieniu marż. Możesz dostosować odchylenie całego łańcucha – w lewo, w prawo, w górę lub w dół – zmieniając odchylenie widoku łańcucha.
Widok „head” łańcucha – najdalej od lewej w łańcuchu poziomym (w układzie od lewej do prawej) i widok znajdujący się najwyżej w pionowym łańcuchu – definiuje styl łańcucha w formacie XML. Możesz jednak przełączać się między widokiem rozproszonym, podziałem w środku i pakowanym, wybierając dowolny widok w łańcuchu i klikając przycisk łańcucha , który pojawi się pod nim.
Aby utworzyć sieć, wykonaj te czynności, tak jak pokazano w filmie 4:
- Wybierz wszystkie widoki danych, które chcesz uwzględnić w łańcuchu.
- Kliknij prawym przyciskiem myszy jeden z widoków.
- Kliknij Sieci.
- Wybierz Wyśrodkuj w poziomie lub Wyśrodkuj w pionie.
Oto kilka kwestii, które warto wziąć pod uwagę podczas korzystania z sieci:
- Widok może być częścią łańcucha pionowego i poziomego, co pozwala tworzyć elastyczne układy siatki.
- Łańcuch działa prawidłowo tylko wtedy, gdy każdy jego koniec jest ograniczony do innego obiektu na tej samej osi, jak widać na ilustracji 14.
- Chociaż łańcuch ma orientację pionową lub poziomą, nie powoduje wyrównania widoków w tym kierunku. Aby uzyskać właściwą pozycję każdego widoku w łańcuchu, zastosuj inne ograniczenia, takie jak ograniczenia wyrównania.
Automatycznie twórz ograniczenia
Zamiast dodawać ograniczenia do każdego widoku podczas umieszczania ich w układzie, możesz przenieść każdy widok na wybrane miejsce w edytorze układu, a następnie kliknąć Wprowadzić ograniczenia , aby automatycznie utworzyć ograniczenia.
Funkcja Ograniczenia wnioskowania skanuje układ, aby określić najskuteczniejszy zestaw ograniczeń dla wszystkich widoków. Ogranicza ono poglądy do aktualnego położenia, a jednocześnie zapewnia elastyczność. Konieczne może być dostosowanie układu, by odpowiadał Twoim potrzebom w przypadku różnych rozmiarów i orientacji ekranu.
Automatyczne łączenie z podmiotem nadrzędnym to osobna funkcja, którą możesz włączyć. Jeśli jest włączona i dodasz widoki podrzędne do widoku nadrzędnego, automatycznie utworzy ona co najmniej 2 ograniczenia dla każdego widoku, gdy dodasz je do układu – ale tylko wtedy, gdy będzie można ograniczyć widok do układu nadrzędnego. Połączenie automatyczne nie ogranicza innych widoków w układzie.
Łączenie automatyczne jest domyślnie wyłączone. Aby ją włączyć, kliknij Włącz automatyczne połączenie z elementem nadrzędnym na pasku narzędzi edytora układów.
Animacje klatek kluczowych
W obrębie ConstraintLayout
możesz animować zmiany rozmiaru i położenia elementów, używając elementów ConstraintSet
i TransitionManager
.
ConstraintSet
to lekki obiekt, który reprezentuje ograniczenia, marginesy i dopełnienie wszystkich elementów podrzędnych w obrębie elementu ConstraintLayout
. Gdy zastosujesz obiekt ConstraintSet
do wyświetlanego elementu ConstraintLayout
, układ zaktualizuje ograniczenia wszystkich jego elementów podrzędnych.
Aby utworzyć animację przy użyciu elementu ConstraintSet
, określ 2 pliki układu, które działają jako początkowe i końcowe klatki kluczowe animacji. Następnie możesz wczytać ConstraintSet
z drugiego pliku klatki kluczowej i zastosować go do wyświetlanego elementu ConstraintLayout
.
Poniższy przykładowy kod pokazuje, jak animować przesunięcie pojedynczego przycisku na dół ekranu.
// MainActivity.kt
fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.keyframe_one)
constraintLayout = findViewById(R.id.constraint_layout) // member variable
}
fun animateToKeyframeTwo() {
val constraintSet = ConstraintSet()
constraintSet.load(this, R.layout.keyframe_two)
TransitionManager.beginDelayedTransition()
constraintSet.applyTo(constraintLayout)
}
// layout/keyframe1.xml // Keyframe 1 contains the starting position for all elements in the animation // as well as final colors and text sizes. <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/button2" android:layout_width="0dp" android:layout_height="wrap_content" android:text="Button" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
// layout/keyframe2.xml // Keyframe 2 contains another ConstraintLayout with the final positions. <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/button2" android:layout_width="0dp" android:layout_height="wrap_content" android:text="Button" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintBottom_toBottomOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
Dodatkowe materiały
Parametr ConstraintLayout
jest używany w aplikacji demonstracyjnej Sunflower.