Utwórz responsywny interfejs użytkownika za pomocą ConstraintLayout   Element Android Jetpack.

Wypróbuj sposób tworzenia wiadomości
Jetpack Compose to zalecany zestaw narzędzi UI na Androida. Dowiedz się, jak pracować z układami w Compose.

ConstraintLayout pozwala tworzyć duże, złożone układy z płaską hierarchią widoków – bez zagnieżdżonych grup widoków. Jest on podobny do RelativeLayout, ponieważ wszystkie widoki są rozmieszczone zgodnie z relacją między widokami siostrzanymi a ich układem nadrzędnym, ale jest bardziej elastyczny niż RelativeLayouti łatwiejszy w użyciu dzięki edytorowi układu w Android Studio.

Wszystkie możliwości interfejsu ConstraintLayout są dostępne bezpośrednio w narzędziach wizualnych Edytora układu, ponieważ interfejs API układu i Edytor układu są ze sobą specjalnie zintegrowane. Układ możesz tworzyć za pomocą elementów ConstraintLayout, przeciągając je, zamiast edytować kod XML.

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

Aby zobaczyć różne układy, które możesz utworzyć za pomocą ConstraintLayout, zapoznaj się z projektem Przykłady układu ograniczeń na GitHubie.

Omówienie ograniczeń

Aby zdefiniować położenie widoku w ConstraintLayout, musisz dodać co najmniej 1 ograniczenie poziome i 1 ograniczenie pionowe. Każde ograniczenie reprezentuje połączenie lub dopasowanie do innego widoku, układu nadrzędnego lub niewidocznej linii pomocniczej. 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żdej osi, ale często potrzebne jest więcej ograniczeń.

Po upuszczeniu widoku w edytorze układów pozostaje on tam, gdzie go opuścisz, nawet jeśli nie ma żadnych ograniczeń. Ma to ułatwić edycję. Jeśli widok nie ma ograniczeń, gdy uruchomisz układ na urządzeniu, zostanie on narysowany w pozycji [0,0] (w lewym górnym rogu).

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

Rysunek 1. Edytor pokazuje widok C poniżej widoku A, ale nie ma ograniczenia pionowego.

Rysunek 2. Widok C jest teraz ograniczony w pionie poniżej widoku A.

Brakujące ograniczenia nie powodują błędów kompilacji, ale edytor układu wskazuje je jako błędy 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ąć braku ograniczeń, edytor układu automatycznie dodaje ograniczenia za pomocą funkcji Autołączanie i wyprowadzanie ograniczeń.

Dodawanie ConstraintLayout do projektu

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

  1. Sprawdź, czy w pliku settings.gradle masz zadeklarowane repozytorium maven.google.com:

    Odlotowe

        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.

    Groovy

    dependencies {
        implementation "androidx.constraintlayout:constraintlayout:2.2.0"
        // To use constraintlayout in compose
        implementation "androidx.constraintlayout:constraintlayout-compose:1.1.0"
    }

    Kotlin

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

Teraz możesz utworzyć układ za pomocą ConstraintLayout.

Konwertowanie układu

Rysunek 3. Menu służące do konwertowania układu 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 na dole okna edytora.
  2. W oknie Drzewo komponentów kliknij prawym przyciskiem myszy układ i kliknij Przekształc układ LinearLayout w ConstraintLayout.

Tworzenie nowego układu

Aby utworzyć nowy plik układu ograniczeń:

  1. W oknie Projekt kliknij folder modułu i wybierz Plik > Nowy > XML > XML układu.
  2. Wpisz nazwę pliku układu, a w polu 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 do ConstraintLayout, pojawi się on w ramce z kwadratowymi uchwytami do zmiany rozmiaru w każdym rogu oraz okrągłym uchwytami ograniczającymi 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. Ten punkt może być krawędzią innego widoku, krawędzią układu lub wskazówką. Gdy przeciągasz uchwyt ograniczenia, w Edytorze układu pojawiają się potencjalne uchwyty połączenia 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.

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

Gdy ograniczenie zostanie utworzone, edytor nada mu domyślny margines, aby oddzielić 2 widoki.

Podczas tworzenia ograniczeń pamiętaj o tych zasadach:

  • Każdy widok musi mieć co najmniej 2 ograniczenia: jedno poziome i jedno pionowe.
  • Ograniczenia możesz 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 zostać ograniczona tylko do innej płaszczyzny pionowej, a linie odniesienia mogą być ograniczone tylko do innych punktów odniesienia.
  • Każdy uchwyt ograniczenia może być używany tylko w przypadku 1 ograniczenia, ale do tego samego punktu zakotwiczenia możesz utworzyć wiele ograniczeń z różnych widoków.

Ograniczenie możesz usunąć, wykonując jedną z tych czynności:

  • Kliknij ograniczenie, aby je zaznaczyć, a potem kliknij Usuń.
  • Kliknij Control (Command w systemie macOS) kotwicę ogranicznika. Ograniczenie ma kolor czerwony, co wskazuje, że można je usunąć kliknięciem, jak pokazano na rysunku 5.

    Rysunek 5. Czerwone ograniczenie oznacza, że możesz je kliknąć, aby je usunąć.

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

    Rysunek 6. Kliknij kotwicę ograniczenia, aby ją usunąć.

Film 2. dodanie ograniczenia, które jest przeciwstawne do istniejącego;

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 „zawijaj treść”, co oznacza, że widok jest wyśrodkowany między ograniczeniami. Jeśli chcesz, aby widok rozciągał się, aby spełniać ograniczenia, zmień rozmiar na „dopasuj do ograniczeń”. 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 zachowania układu, jak opisano w następnych sekcjach.

Pozycja nadrzędna

Ogranicz stronę widoku do odpowiadającej krawędzi układu.

Na rysunku 7 lewa strona widoku jest połączona z lewym marginesem głównego układu. Odległość od krawędzi możesz określić za pomocą marginesu.

Rysunek 7. Ograniczenie poziome do elementu nadrzędnego.

Pozycja zamówienia

Określ kolejność wyświetlania 2 widoków: pionowo lub poziomo.

Na ilustracji 8 obiekt B jest zawsze ograniczony do prawej strony, a C – poniżej A. Ograniczenia te nie oznaczają jednak wyrównania, więc wskaźnik B może się swobodnie przesuwać w górę lub w dół.

Rysunek 8. Ograniczenie poziome i pionowy.

Wyrównanie

wyrównać krawędź widoku do 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 widoku, utwórz ograniczenie po obu stronach.

Możesz przesunąć widok w kierunku ograniczenia, przeciągając go w głąb. Na przykład rysunek 10 przedstawia element B z wyrównaniem przesuniętym o 24 piksele. Przesunięcie jest określane przez margines widoku ograniczonego.

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

Rysunek 9. Ograniczenie wyrównania w poziomie.

Rysunek 10. Ograniczenie odsunięcia wyrównania w poziomie.

Wyrównanie do linii bazowej

Wyrównaj linię bazową tekstu w widoku do linii bazowej tekstu w innym widoku.

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

Aby utworzyć ograniczenie wartości bazowej, kliknij prawym przyciskiem widok tekstu, który chcesz ograniczyć, a następnie kliknij Pokaż wartość bazową. Następnie kliknij tekst na linii bazowej i przeciągnij tę linię do innej linii bazowej.

Rysunek 11. Ograniczenie wyrównania do wartości podstawowej.

Ogranicz do wytycznych

Możesz dodać linię pomocniczą pionową lub poziomą, która ograniczy widok, a która jest niewidoczna dla użytkowników aplikacji. Możesz ustawić położenie linii pomocniczej w ramach układu na podstawie jednostek dp lub procenta w stosunku do krawędzi układu.

Aby utworzyć wytyczne, na pasku narzędzi kliknij Wytyczne , a następnie Dodaj wytyczne pionowe lub Dodaj wytyczne poziome.

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

Rysunek 12. Widok ograniczony do wytycznych.

Ograniczenie do bariery

Podobnie jak wytyczna, bariera jest niewidzialną linią, którą możesz ograniczyć widoki, ale nie określa ona własnej pozycji. Zamiast tego pozycja bariery zmienia się w zależności od pozycji widoków, które zawiera. Jest to przydatne, gdy chcesz ograniczyć widok do wybranego zestawu widoków, a nie do jednego.

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

Aby utworzyć barierę:

  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 bariery, i przeciągnij je do komponentu bariery.
  3. Wybierz barierę w drzewie komponentów, otwórz okno Atrybuty i ustaw opcję kierunekBariery.

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

Możesz też ograniczyć widoki wewnątrz bariery. Dzięki temu możesz dopasować wszystkie widoki w barierze do siebie nawzajem, nawet jeśli nie wiesz, który z nich jest najdłuższy lub najwyższy.

Możesz też umieścić w barierze wskazówkę, aby zapewnić jej „minimalną” pozycję.

Rysunek 13. Widok C jest ograniczony do bariery, która przesuwa się w zależności od położenia i rozmiaru widoku A oraz widoku B.

Dostosowywanie wartości domyślnej ograniczeń

Gdy dodasz ograniczenie po obu stronach widoku, a rozmiar widoku dla tego samego wymiaru będzie miał wartość „stały” lub „zawijaj treść”, widok zostanie wyśrodkowany między tymi dwoma ograniczeniami, a odchylenie będzie domyślnie równe 50%. Możesz dostosować 偏差 (bias) przez przeciąganie suwaka w oknie Atrybuty lub przez przeciąganie widoku, jak pokazano w filmie 3.

Jeśli zamiast tego chcesz, aby widok rozciągał się zgodnie z ograniczeniami, przełącz rozmiar na „Dopasuj ograniczenia”.

Film 3. Dostosowywanie uprzedzeń ograniczenia.

Dostosowywanie rozmiaru widoku

Rysunek 14. Podczas wybierania widoku okno Atrybuty zawiera opcje kontroli współczynnika rozmiaru 1, 2 usuwania ograniczeń, 3 trybu wysokości lub szerokości, 4 marginesy i 5 odchylenia ograniczenia. W edytorze układu możesz też zaznaczyć poszczególne ograniczenia, klikając je na liście ograniczeń 6.

Możesz zmienić rozmiar widoku za pomocą uchwytów narożnych, ale ten rozmiar jest zakodowany na stałe – widok nie zmienia się w zależności od zawartości czy rozmiaru ekranu. Aby wybrać inny tryb określania rozmiaru, kliknij widok i otwórz okno Atrybuty po prawej stronie edytora.

U góry okna Atrybuty znajduje się kontroler widoku, który zawiera ustawienia kilku atrybutów układu, jak pokazano na rysunku 14. Jest to możliwe tylko w przypadku widoków w układzie z ograniczeniami.

Aby zmienić sposób obliczania wysokości i szerokości, kliknij symbole wskazane strzałką 3 na rysunku 14. Te symbole oznaczają tryb rozmiaru w następujący sposób. Kliknij symbol, aby przełączać się między tymi ustawieniami:

  • Stały: w tym celu wskaż konkretny wymiar w polu tekstowym poniżej lub zmień rozmiar widoku w edytorze.
  • Zawijanie treści: widok rozszerza się tylko do tego stopnia, aby zmieścić zawartość.
    • layout_constrainedWidth
    • Ustaw wartość true, aby wymiar poziomy mógł się zmieniać z uwzględnieniem ograniczeń. Domyślnie widżet ustawiony na WRAP_CONTENTnie jest ograniczony przez ograniczenia.

  • Ograniczenia dopasowania: widok rozszerza się tak bardzo, jak to możliwe, aby spełniać ograniczenia po obu stronach, uwzględniając marginesy widoku. Możesz jednak zmodyfikować 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

      Spowoduje to ustawienie wymiaru dp na potrzeby minimalnej szerokości widoku.

    • layout_constraintWidth_max

      W przypadku maksymalnej szerokości widoku używa się wymiaru dp.

    Jeśli jednak dany wymiar ma tylko 1 ograniczenie, widok rozszerza się, aby dopasować zawartość. Użycie tego trybu w przypadku wysokości lub szerokości pozwala też ustawić współczynnik rozmiaru.

Określ rozmiar jako współczynnik

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

Jeśli co najmniej 1 z wymiarów widoku jest ustawiony na „ograniczenia dopasowania” (0dp), możesz ustawić rozmiar widoku na określony współczynnik, np. 16:9. Aby włączyć ten współczynnik, kliknij Przełącz ograniczenie współczynnika proporcji (objaśnienie 1 na ilustracji 14) i wpisz wartość width:height w wyświetlonych danych wejściowych.

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

Jeśli np. dla obu stron ustawisz „Dopasuj do ograniczeń”, kliknij dwukrotnie Przełącz ograniczenie współczynnika proporcji, aby ustawić szerokość jako współczynnik wysokości. Cały rozmiar zależy od wysokości widoku, którą można zdefiniować w dowolny sposób, jak widać na rysunku 15.

Dostosowywanie marginesów widoku

Aby wyrównać widoki, na pasku narzędzi kliknij Margines , aby wybrać domyślne marginesy dla każdego widoku, który dodajesz do układu. Wszelkie zmiany domyślnej marży mają zastosowanie tylko do widoków dodanych od tego momentu.

Możesz kontrolować marżę w przypadku każdego widoku w oknie Atrybuty, klikając liczbę w wierszu, który reprezentuje dany warunek. Na ilustracji 14 objaśnienie 4 pokazuje dolny margines ustawiony na 16 dp.

Rysunek 16. Przycisk Margin na pasku narzędzi.

Wszystkie marginesy oferowane przez narzędzie są wielokrotnościami 8 dp, aby ułatwić dopasowanie widoków do zaleceń dotyczących siatki kwadratowej o wymiarach 8 dp w ramach Material Design.

Sterowanie grupami liniowymi za pomocą łańcucha

Rysunek 17. Łańcuch poziomy z 2 widokami.

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

Rysunek 18. Przykłady każdego stylu łańcucha.

Łańcuchy można stylizować na jeden z tych sposobów:

  1. Spread: widoki są równomiernie rozłożone po uwzględnieniu marż. Jest to ustawienie domyślne.
  2. Rozprowadź wewnątrz: pierwsze i ostatnie wyświetlenia są przypisane do ograniczeń po obu końcach łańcucha, a pozostałe są równomiernie rozłożone.
  3. Ważone: gdy łańcuch jest ustawiony jako rozłożony lub rozciągnięty w środku, możesz wypełnić pozostałą przestrzeń, ustawiając dla jednego lub większej liczby widoków „dopasowanie ograniczeń” (0dp). Domyślnie przestrzeń jest równomiernie rozdzielana między wszystkie widoki danych, dla których ustawiono „ograniczenia zgodności”, ale możesz przypisać wagę każdemu widokowi za pomocą atrybutów layout_constraintHorizontal_weight i layout_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. Zpakowane: widoki są pakowane po uwzględnieniu marż. Możesz dostosować ustawienie całego łańcucha – w lewo lub w prawo, w górę lub w dół – przez zmianę ustawienia widoku „głowy” łańcucha.

Widok „head” łańcucha – widok skrajnie od lewej w łańcuchu poziomym (w układzie od lewej do prawej) i widok skrajny w pionie w łańcuchu pionowym – definiuje styl łańcucha w pliku XML. Możesz jednak przełączać się między opcjami rozproszenie, rozproszenie wewnątrz i zbiorzone, wybierając dowolny widok w łańcuchu i klikając przycisk , który pojawi się pod widokiem.

Aby utworzyć łańcuch, wykonaj te czynności, jak pokazano w filmie 4:

  1. Wybierz wszystkie widoki, które mają być uwzględnione w łańcuchu.
  2. Kliknij prawym przyciskiem myszy jeden z widoków.
  3. Wybierz Sieć.
  4. Wybierz Do środka poziomo lub Do środka pionowo.

Film 4. Tworzenie łańcucha poziomego.

Oto kilka kwestii, które warto wziąć pod uwagę podczas tworzenia ł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 każdy jego koniec jest ograniczony do innego obiektu na tej samej osi, jak pokazano na rysunku 14.
  • Chociaż orientacja łańcucha jest pionowa lub pozioma, korzystanie z niego nie powoduje wyrównywania widoków w tym kierunku. Aby umieścić odpowiednie położenie każdego widoku w łańcuchu, uwzględnij inne ograniczenia, takie jak ograniczenia wyrównania.

Automatycznie twórz ograniczenia

Zamiast dodawać ograniczenia do każdego widoku podczas umieszczania go w układzie, możesz przenieść każdy widok w wybrane miejsca w Edytorze układu, a następnie kliknąć Wnioskowanie ograniczeń , aby utworzyć ograniczenia automatycznie.

Wnioskowanie ograniczeń skanuje układ, aby określić najbardziej skuteczny zestaw ograniczeń dla wszystkich widoków. Ogranicza widoki do ich aktualnych pozycji, zapewniając przy tym elastyczność. Może być konieczne wprowadzenie poprawek, aby układ działał elastycznie zgodnie z zamierzeniami na różnych rozmiarach i orientacjach ekranu.

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

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

Animacje klatek kluczowych

W elemencie ConstraintLayout możesz animować zmiany rozmiaru i pozycji elementów za pomocą tagów ConstraintSet i TransitionManager.

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

Aby utworzyć animację przy użyciu ConstraintSet, określ 2 pliki układu, które będą działać jako początkowa i końcowa klatka kluczowa animacji. Następnie możesz załadować ConstraintSet z drugiego pliku klatki kluczowej i zastosować go do wyświetlanego ConstraintLayout.

Ten przykład kodu pokazuje, jak animować przenoszenie 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

ConstraintLayout jest używany w aplikacji demonstracyjnej Sunflower.