Tworzenie elastycznego interfejsu za pomocą ConstraintLayout, części Androida Jetpack.

Wypróbuj metodę Compose
Jetpack Compose to zalecany zestaw narzędzi interfejsu na Androida. Dowiedz się, jak pracować z układami w Compose.

ConstraintLayout umożliwia tworzenie dużych, złożonych układów z płaską hierarchią widoków – bez zagnieżdżonych grup widoków. Jest podobny do RelativeLayout, ponieważ wszystkie widoki są rozmieszczone zgodnie z relacjami między widokami równorzędnymi a układem nadrzędnym, ale jest bardziej elastyczny niż RelativeLayout i łatwiejszy w użyciu w edytorze układu Androida Studio.

Wszystkie funkcje ConstraintLayout są dostępne bezpośrednio w narzędziach wizualnych Edytora układu, ponieważ interfejs API układu i Edytor układu zostały stworzone specjalnie z myślą o sobie. Układ możesz tworzyć ConstraintLayout w całości, przeciągając elementy zamiast edytować kod XML.

Na tej stronie dowiesz się, jak utworzyć układ za pomocą ConstraintLayout w Androidzie Studio 3.0 lub nowszym. Więcej informacji o edytorze układu znajdziesz w artykule Tworzenie interfejsu za pomocą edytora układu.

Aby zobaczyć różne układy, które możesz utworzyć za pomocą ConstraintLayout, zapoznaj się z projektem Constraint Layout Examples w GitHubie.

Omówienie ograniczeń

Aby określić położenie widoku w ConstraintLayout, dodaj co najmniej 1 ograniczenie poziome i 1 ograniczenie pionowe. Każde ograniczenie reprezentuje połączenie lub wyrównanie z innym widokiem, układem nadrzędnym lub niewidoczną linią pomocniczą. Każde ograniczenie określa położenie widoku wzdłuż osi pionowej lub poziomej. Każdy widok musi mieć co najmniej 1 ograniczenie dla każdego z osi, ale często potrzebnych jest więcej.

Gdy umieścisz widok w narzędziu Layout Editor, pozostanie on w tym miejscu, nawet jeśli nie ma żadnych ograniczeń. Ma to tylko ułatwić edycję. Jeśli widok nie ma ograniczeń podczas uruchamiania układu na urządzeniu, jest rysowany w pozycji [0,0] (w lewym górnym rogu).

Na rysunku 1 układ wygląda dobrze w edytorze, ale nie ma pionowego ograniczenia widoku C. Gdy ten układ jest rysowany na urządzeniu, widok C jest wyrównany poziomo do lewej i prawej krawędzi widoku A, ale pojawia się u góry ekranu, ponieważ nie ma ograniczenia pionowego.

Rysunek 1. Edytor wyświetla widok C pod widokiem A, ale nie ma on ograniczenia pionowego.

Rysunek 2. Widok C jest teraz ograniczony pionowo pod widokiem A.

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 pomóc Ci uniknąć brakujących ograniczeń, [narzędzie] Layout Editor automatycznie dodaje ograniczenia za pomocą funkcji Automatyczne łączenie i wywnioskowanie ograniczeń.

Dodawanie ConstraintLayout do projektu

Aby używać ConstraintLayout w projekcie, wykonaj te czynności:

  1. Upewnij się, że w pliku settings.gradle zadeklarowano repozytorium maven.google.com:

    Dynamiczny

        dependencyResolutionManagement {
          ...
          repositories {
              google()
          }
        )
        

    Kotlin

        dependencyResolutionManagement {
          ...
          repositories {
              google()
          }
        }
        
  2. Dodaj bibliotekę jako zależność w pliku build.gradle na poziomie modułu, jak pokazano w tym przykładzie. Najnowsza wersja może się różnić od tej pokazanej w przykładzie.

    Odlotowe

    dependencies {
        implementation "androidx.constraintlayout:constraintlayout:2.2.1"
        // To use constraintlayout in compose
        implementation "androidx.constraintlayout:constraintlayout-compose:1.1.1"
    }

    Kotlin

    dependencies {
        implementation("androidx.constraintlayout:constraintlayout:2.2.1")
        // To use constraintlayout in compose
        implementation("androidx.constraintlayout:constraintlayout-compose:1.1.1")
    }
  3. Na pasku narzędzi lub w powiadomieniu o synchronizacji kliknij Sync Project with Gradle Files (Synchronizuj projekt z plikami Gradle).

Możesz teraz utworzyć układ za pomocą ConstraintLayout.

Konwertowanie układu

Rysunek 3. Menu, w którym możesz przekonwertować układ na ConstraintLayout.

Aby przekonwertować istniejący układ na układ z ograniczeniami, wykonaj te czynności:

  1. Otwórz układ w Android Studio i kliknij kartę Projekt u dołu okna edytora.
  2. W oknie Component Tree (Drzewo komponentów) kliknij prawym przyciskiem myszy układ i wybierz Convert LinearLayout to ConstraintLayout (Przekształć LinearLayout w ConstraintLayout).

Tworzenie nowego układu

Aby utworzyć nowy plik układu z ograniczeniami, wykonaj te czynności:

  1. W oknie Project (Projekt) kliknij folder modułu i wybierz File > New > XML > Layout XML (Plik > Nowy > XML > XML układu).
  2. Wpisz nazwę pliku układu i w polu Root Tag (Tag główny) wpisz „androidx.constraintlayout.widget.ConstraintLayout”.
  3. Kliknij Zakończ.

Dodawanie i usuwanie ograniczeń

Aby dodać ograniczenie:

Film 1. Lewa strona widoku jest ograniczona do lewej strony elementu nadrzędnego.

  1. Przeciągnij widok z okna Paleta do edytora.

    Gdy dodasz widok w ConstraintLayout, pojawi się on w ramce ograniczającej z kwadratowymi uchwytami zmiany rozmiaru w każdym rogu i okrągłymi uchwytami ograniczeń po każdej stronie.

  2. Kliknij widok, aby go wybrać.
  3. 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ędź układu lub linia pomocnicza. Zwróć uwagę, że podczas przeciągania uchwytu ograniczenia Edytor układu wyświetla potencjalne punkty zaczepienia połączenia i niebieskie nakładki.
    • W sekcji Układ okna Atrybuty kliknij jeden z przycisków Utwórz połączenie, jak pokazano na ilustracji 4.

      Rysunek 4. Sekcja Układ w oknie Atrybuty umożliwia tworzenie połączeń.

Po utworzeniu ograniczenia edytor nadaje mu domyślny margines, aby oddzielić od siebie 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 znajdują się na tej samej płaszczyźnie. Płaszczyzna pionowa (lewa i prawa strona widoku) może być ograniczona tylko do innej płaszczyzny pionowej, a linie bazowe mogą być ograniczone tylko do innych linii bazowych.
  • Każdy uchwyt ograniczenia może być używany tylko w przypadku jednego ograniczenia, ale możesz utworzyć wiele ograniczeń z różnych widoków do tego samego punktu zakotwiczenia.

Ograniczenie możesz usunąć na jeden z tych sposobów:

  • Kliknij ograniczenie, aby je zaznaczyć, a potem kliknij Usuń.
  • Kliknij z naciśniętym klawiszem Control (w systemie macOS kliknij z naciśniętym klawiszem Command) kotwicę ograniczenia. Ograniczenie zmieni kolor na czerwony, co oznacza, że możesz je usunąć, klikając je (rysunek 5).

    Rysunek 5. Czerwone ograniczenie oznacza, że możesz je usunąć, klikając je.

  • W sekcji Układ okna Atrybuty kliknij kotwicę ograniczenia, jak pokazano na rysunku 6.

    Rysunek 6. Kliknij punkt zakotwiczenia ograniczenia, aby je usunąć.

Film 2. Dodanie ograniczenia, które jest sprzeczne z istniejącym.

Jeśli dodasz do widoku przeciwstawne ograniczenia, linie ograniczeń zwiną się jak sprężyna, aby wskazać przeciwstawne siły, jak pokazano w filmie 2. Efekt jest najbardziej widoczny, gdy rozmiar widoku jest ustawiony na „stały” lub „zawijanie treści”, w którym to przypadku widok jest wyśrodkowany między ograniczeniami. Jeśli chcesz, aby widok rozciągał się, aby spełnić ograniczenia, zmień rozmiar na „dopasuj do ograniczeń”. Jeśli chcesz zachować bieżący rozmiar, ale przesunąć widok, aby nie był wyśrodkowany, dostosuj odchylenie ograniczenia.

Za pomocą ograniczeń możesz uzyskać różne typy zachowań układu, jak opisano w kolejnych sekcjach.

Pozycja elementu nadrzędnego

Ogranicz bok widoku do odpowiedniej krawędzi układu.

Na rysunku 7 lewa strona widoku jest połączona z lewą krawędzią układu nadrzędnego. Odległość od krawędzi możesz określić za pomocą marginesu.

Rysunek 7. Ograniczenie poziome względem elementu nadrzędnego.

Pozycja zamówienia

Określ kolejność wyświetlania dwóch widoków w pionie lub w poziomie.

Na rysunku 8 punkt B jest zawsze po prawej stronie punktu A, a punkt C jest poniżej punktu A. Te ograniczenia nie oznaczają jednak wyrównania, więc element B może nadal przesuwać się w górę i w dół.

Rysunek 8. Ograniczenie poziome i pionowe.

Wyrównanie

Wyrównaj krawędź widoku do tej samej krawędzi innego widoku.

Na rysunku 9 lewa strona elementu B jest wyrównana do lewej strony elementu A. Jeśli chcesz wyrównać środki widoków, utwórz ograniczenie po obu stronach.

Możesz przesunąć wyrównanie, przeciągając widok do wewnątrz od ograniczenia. Na przykład na rysunku 10 widać element B z wyrównaniem z przesunięciem 24 dp. Przesunięcie jest określone przez margines widoku z ograniczeniami.

Możesz też zaznaczyć wszystkie widoki, które chcesz wyrównać, a następnie na pasku narzędzi kliknąć Wyrównaj , aby wybrać typ wyrównania.

Rysunek 9. Ograniczenie wyrównania w poziomie.

Rysunek 10. Ograniczenie wyrównania poziomego z odsunięciem.

Wyrównanie do linii bazowej

Wyrównaj linię bazową tekstu w jednym widoku z linią bazową tekstu w innym widoku.

Na rysunku 11 pierwszy wiersz w kolumnie B jest wyrównany do tekstu w kolumnie A.

Aby utworzyć ograniczenie linii bazowej, 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.

Rysunek 11. Ograniczenie wyrównania do linii bazowej.

Ograniczanie do linii pomocniczej

Możesz dodać pionową lub poziomą linię pomocniczą, która ogranicza widoki i jest niewidoczna dla użytkowników aplikacji. Linię pomocniczą możesz umieścić w układzie na podstawie jednostek dp lub procentu względem krawędzi układu.

Aby utworzyć linię pomocniczą, na pasku narzędzi kliknij Linie pomocnicze , a następnie kliknij Dodaj pionową linię pomocniczą lub Dodaj poziomą linię pomocniczą.

Przeciągnij linię przerywaną, aby zmienić jej położenie, a następnie kliknij kółko na krawędzi linii pomocniczej, aby przełączyć tryb pomiaru.

Rysunek 12. Widok ograniczony do linii pomocniczej.

Ograniczenie do bariery

Podobnie jak wytyczna, bariera jest niewidoczną linią, do której możesz ograniczyć widoki, z tym wyjątkiem, że bariera nie określa własnej pozycji. Zamiast tego pozycja bariery zmienia się w zależności od pozycji widoków, które się w niej znajdują. Jest to przydatne, gdy chcesz ograniczyć widok do zestawu widoków, a nie do jednego konkretnego widoku.

Na przykład na rysunku 13 widok C jest ograniczony do prawej strony bariery. Bariera jest ustawiona na „końcu” (lub po prawej stronie w układzie od lewej do prawej) zarówno w widoku A, jak i w widoku B. Bariera przesuwa się w zależności od tego, czy najbardziej po prawej stronie znajduje się widok A czy widok B.

Aby utworzyć barierę, wykonaj te czynności:

  1. Na pasku narzędzi kliknij Wytyczne a następnie Dodaj barierę pionową lub Dodaj barierę poziomą.
  2. W oknie Drzewo komponentów wybierz widoki, które chcesz umieścić w komponencie bariery, i przeciągnij je do tego komponentu.
  3. Wybierz barierę w drzewie komponentów, otwórz okno Atrybuty i ustaw barrierDirection.

Teraz możesz utworzyć ograniczenie z innego widoku do bariery.

Możesz też ograniczyć widoki, które znajdują się wewnątrz bariery, do tej bariery. Dzięki temu możesz wyrównać wszystkie widoki w bloku względem siebie, nawet jeśli nie wiesz, który widok jest najdłuższy lub najwyższy.

Możesz też umieścić w barierce linię pomocniczą, aby zapewnić jej „minimalne” położenie.

Rysunek 13. Widok C jest ograniczony barierą, która przesuwa się w zależności od pozycji i rozmiaru widoków A i B.

Dostosowywanie odchylenia ograniczenia

Gdy dodasz ograniczenie po obu stronach widoku, a rozmiar widoku w tym samym wymiarze będzie „stały” lub „zawijaj treść”, widok zostanie wyśrodkowany między dwoma ograniczeniami z domyślnym odchyleniem wynoszącym 50%. Odchylenie możesz dostosować, przeciągając suwak odchylenia w oknie Atrybuty lub przeciągając widok, jak pokazano w filmie 3.

Jeśli chcesz, aby widok rozciągał się, aby spełnić ograniczenia, zmień rozmiar na „dopasuj do ograniczeń”.

Film 3. Dostosowywanie odchylenia ograniczenia.

Dostosowywanie rozmiaru widoku

Rysunek 14. Po wybraniu widoku okno Atrybuty zawiera elementy sterujące:1 współczynnikiem rozmiaru,2 usuwaniem ograniczeń,3 trybem wysokości lub szerokości,4 marginesami i5 odchyleniem ograniczenia. Możesz też wyróżnić poszczególne ograniczenia w [narzędziu] Layout Editor, klikając je na liście ograniczeń 6.

Uchwytów w rogach możesz używać do zmiany rozmiaru widoku, ale w ten sposób na stałe ustawisz rozmiar – widok nie będzie się dostosowywać do różnych treści ani rozmiarów ekranu. Aby wybrać inny tryb zmiany rozmiaru, kliknij widok i otwórz okno Atrybuty po prawej stronie edytora.

U góry okna Atrybuty znajduje się inspektor widoku, który zawiera elementy sterujące kilkoma atrybutami układu, jak pokazano na rysunku 14. Jest to dostępne tylko w przypadku widoków w układzie z ograniczeniami.

Sposób obliczania wysokości i szerokości możesz zmienić, klikając symbole oznaczone w rysunku 14 wywołaniem 3. Symbole te oznaczają tryb rozmiaru w ten sposób: Kliknij symbol, aby przełączać się między tymi ustawieniami:

  • Stały: określ konkretny wymiar w polu tekstowym poniżej lub zmieniając rozmiar widoku w edytorze.
  • Zawijaj zawartość: widok rozszerza się tylko na tyle, na ile jest to potrzebne, aby zmieścić zawartość.
    • layout_constrainedWidth
    • Ustaw tę wartość na true, aby umożliwić zmianę wymiaru poziomego w celu zachowania ograniczeń. Domyślnie widżet ustawiony na WRAP_CONTENTnie jest ograniczony przez żadne warunki.

  • Ograniczenia dopasowania: widok rozszerza się maksymalnie, aby spełnić ograniczenia po każdej stronie, po uwzględnieniu marginesów widoku. Możesz jednak zmienić to zachowanie za pomocą tych atrybutów i wartości. Te atrybuty działają tylko wtedy, gdy ustawisz szerokość widoku na „dopasuj do ograniczeń”:
    • layout_constraintWidth_min

      Wymaga to wymiaru dp dla minimalnej szerokości widoku.

    • layout_constraintWidth_max

      W tym przypadku wymiar dp określa maksymalną szerokość widoku.

    Jeśli jednak dany wymiar ma tylko jedno ograniczenie, widok rozszerza się, aby dopasować się do jego zawartości. Użycie tego trybu w przypadku wysokości lub szerokości umożliwia też ustawienie współczynnika rozmiaru.

Ustawianie rozmiaru jako współczynnika

Rysunek 15. Widok jest ustawiony na format 16:9, a szerokość jest określana na podstawie stosunku wysokości.

Możesz ustawić rozmiar widoku jako stosunek, np. 16:9, jeśli co najmniej jeden z wymiarów widoku jest ustawiony na „dopasuj do ograniczeń” (0dp). Aby włączyć stosunek, kliknij Przełącz ograniczenie proporcji (etykieta 1 na rysunku 14) i wpisz stosunek width:height w wyświetlonym polu.

Jeśli zarówno szerokość, jak i wysokość są ustawione na „dopasuj do ograniczeń”, możesz kliknąć Przełącz ograniczenie współczynnika proporcji, aby wybrać, który wymiar ma być oparty na współczynniku drugiego. Inspektor widoku wskazuje, który wymiar jest ustawiony jako współczynnik, łącząc odpowiednie krawędzie linią ciągłą.

Jeśli np. ustawisz obie strony na „dopasuj do ograniczeń”, kliknij Przełącz ograniczenie współczynnika proporcji 2 razy, aby ustawić szerokość jako stosunek wysokości. Cały rozmiar jest określany przez wysokość widoku, którą można zdefiniować w dowolny sposób, jak pokazano na rysunku 15.

Dostosowywanie marginesów widoku

Aby widoki były równomiernie rozmieszczone, na pasku narzędzi kliknij Margines , aby wybrać domyślny margines dla każdego widoku dodawanego do układu. Wszelkie zmiany domyślnego marginesu będą miały zastosowanie tylko do widoków dodawanych od tego momentu.

Margines każdego widoku możesz kontrolować w oknie Atrybuty, klikając liczbę w wierszu, który reprezentuje każde ograniczenie. Na rysunku 14 wywołanie 4 pokazuje, że dolny margines jest ustawiony na 16 dp.

Rysunek 16. Przycisk Margines na pasku narzędzi.

Wszystkie marginesy oferowane przez to narzędzie są wielokrotnością 8 dp, co pomaga dopasować widoki do zaleceń dotyczących siatki kwadratowej o rozmiarze 8 dp w Material Design.

Sterowanie grupami liniowymi za pomocą łańcucha

Rysunek 17. Poziomy łańcuch z 2 widokami.

Łańcuch to grupa widoków połączonych ze sobą za pomocą dwukierunkowych ograniczeń pozycji. Widoki w łańcuchu mogą być rozmieszczone pionowo lub poziomo.

Rysunek 18. Przykłady poszczególnych rodzajów łańcuszków.

Łańcuchy można formatować na kilka sposobów:

  1. Rozkład: wyświetlenia są równomiernie rozłożone po uwzględnieniu marż. Jest to ustawienie domyślne.
  2. Rozmieszczenie wewnątrz: pierwsze i ostatnie wyświetlenie są przypisane do ograniczeń na każdym końcu łańcucha, a pozostałe są równomiernie rozłożone.
  3. Ważone: gdy łańcuch jest ustawiony na rozłożony lub rozłożony wewnątrz, możesz wypełnić pozostałe miejsce, ustawiając co najmniej jeden widok na „dopasuj do ograniczeń” (0dp). Domyślnie miejsce jest równomiernie rozdzielane między poszczególne widoki ustawione na „dopasuj do ograniczeń”, ale możesz przypisać wagę ważności do każdego widoku za pomocą atrybutów layout_constraintHorizontal_weightlayout_constraintVertical_weight. Działa to tak samo jak layout_weightukładzie liniowym: widok o najwyższej wartości wagi zajmuje najwięcej miejsca, a widoki o tej samej wadze zajmują tyle samo miejsca.
  4. Upakowane: widoki są upakowane po uwzględnieniu marginesów. Możesz dostosować odchylenie całego łańcucha w lewo lub w prawo albo w górę lub w dół, zmieniając odchylenie widoku „głowy” łańcucha.

Widok „głowy” łańcucha – widok najbardziej po lewej stronie w łańcuchu poziomym (w układzie od lewej do prawej) i widok najbardziej u góry w łańcuchu pionowym – określa styl łańcucha w XML. Możesz jednak przełączać się między opcjami rozłożony, rozłożony wewnątrzspakowany, wybierając dowolny widok w łańcuchu i klikając przycisk łańcucha , który pojawia się pod widokiem.

Aby utworzyć łańcuch, wykonaj te czynności (zobacz film 4):

  1. Wybierz wszystkie widoki, które mają być uwzględnione w łańcuchu.
  2. Kliknij prawym przyciskiem myszy jeden z widoków.
  3. Kliknij Sieci.
  4. Wybierz Wyśrodkuj w poziomie lub Wyśrodkuj w pionie.

Film 4. Tworzenie łańcucha poziomego.

Oto kilka kwestii, które warto wziąć pod uwagę podczas korzystania z łańcuchów:

  • Widok może być częścią łańcucha poziomego i pionowego, dzięki czemu możesz tworzyć elastyczne układy siatki.
  • Łańcuch działa prawidłowo tylko wtedy, gdy oba jego końce są ograniczone do innego obiektu na tej samej osi, jak pokazano na rysunku 14.
  • Chociaż orientacja łańcucha jest pionowa lub pozioma, użycie jednego z nich nie powoduje wyrównania widoków w tym kierunku. Aby uzyskać odpowiednią pozycję każdego widoku w łańcuchu, uwzględnij inne ograniczenia, np. ograniczenia wyrównania.

Automatyczne tworzenie ograniczeń

Zamiast dodawać ograniczenia do każdego widoku podczas umieszczania go w układzie, możesz przenieść każdy widok do wybranej pozycji w narzędziu Layout Editor, a następnie kliknąć Infer Constraints (Wywnioskuj ograniczenia), aby automatycznie utworzyć ograniczenia.

Infer Constraints skanuje układ, aby określić najskuteczniejszy zestaw ograniczeń dla wszystkich widoków. Ogranicza widoki do ich bieżących pozycji, zapewniając jednocześnie elastyczność. Może być konieczne wprowadzenie zmian, aby układ reagował zgodnie z Twoimi oczekiwaniami na ekranach o różnych rozmiarach i orientacjach.

Automatyczne łączenie z rodzicem to osobna funkcja, którą możesz włączyć. Gdy ta funkcja jest włączona i dodajesz widoki podrzędne do widoku nadrzędnego, automatycznie tworzy ona co najmniej 2 ograniczenia dla każdego widoku podczas dodawania go do układu, ale tylko wtedy, gdy jest to odpowiednie do ograniczenia widoku do układu nadrzędnego. Automatyczne łączenie nie tworzy ograniczeń dla innych widoków w układzie.

Łączenie automatyczne jest domyślnie wyłączone. Aby go włączyć, na pasku narzędzi Edytora układu kliknij Włącz automatyczne łączenie z elementem nadrzędnym .

Animacje klatek kluczowych

ConstraintLayout możesz animować zmiany rozmiaru i położenia elementów za pomocą ConstraintSetTransitionManager.

ConstraintSet to lekki obiekt, który reprezentuje ograniczenia, marginesy i wypełnienie wszystkich elementów podrzędnych w ramach ConstraintLayout. Gdy zastosujesz ConstraintSet do wyświetlanego ConstraintLayout, układ zaktualizuje ograniczenia wszystkich jego elementów podrzędnych.

Aby utworzyć animację za pomocą ConstraintSet, określ 2 pliki układu, które będą pełnić funkcję początkowej i końcowej klatki kluczowej animacji. Następnie możesz wczytać ConstraintSet z drugiego pliku klatki kluczowej i zastosować go do wyświetlanego ConstraintLayout.

Poniższy przykład kodu pokazuje, jak animować przenoszenie jednego 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

ConstraintLayout jest używany w aplikacji w wersji demonstracyjnej Sunflower.