Przenoszenie widoku za pomocą animacji

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

Obiekty na ekranie często trzeba przemieszczać ze względu na interakcje użytkownika lub przetwarzanie w tle. Zamiast natychmiast aktualizować położenie obiektu, przez co mruga z jednego obszaru na drugi, użyj animacji, aby przenieść go z pozycji początkowej do końcowej.

Android umożliwia zmianę położenia obiektów na ekranie za pomocą ObjectAnimator. Musisz podać pozycję końcową, w której ma się zatrzymać obiekt, oraz czas trwania animacji. Możesz też używać interpolatorów czasowych do sterowania przyspieszaniem lub spowalnianiem animacji.

Zmiana pozycji widoku za pomocą narzędzia ObjectAnimator

Interfejs API ObjectAnimator umożliwia zmianę właściwości widoku o określonym czasie trwania. Zawiera on metody statyczne do tworzenia instancji ObjectAnimator w zależności od typu animowanego atrybutu. Aby zmienić pozycję widoku na ekranie, użyj atrybutów translationX i translationY.

Oto przykład elementu ObjectAnimator, który w 2 sekundy przesuwa widok o 100 pikseli od lewej krawędzi ekranu:

Kotlin

ObjectAnimator.ofFloat(view, "translationX", 100f).apply {
    duration = 2000
    start()
}

Java

ObjectAnimator animation = ObjectAnimator.ofFloat(view, "translationX", 100f);
animation.setDuration(2000);
animation.start();

W tym przykładzie użyto metody ObjectAnimator.ofFloat(), ponieważ wartości tłumaczenia muszą być typu float. Pierwszy parametr to widok, który chcesz animować. Drugi parametr to właściwość, którą chcesz animować. Ponieważ widok musi się przesuwać w poziomie, używana jest właściwość translationX. Ostatni parametr to wartość końcowa animacji. W tym przykładzie wartość 100 wskazuje pozycję o tyle pikseli od lewej strony ekranu.

Następna metoda określa czas trwania animacji w milisekundach. W tym przykładzie animacja trwa 2 sekundy (2000 ms).

Ostatnia metoda powoduje uruchomienie animacji, która aktualizuje pozycję widoku na ekranie.

Więcej informacji o korzystaniu z ObjectAnimator znajdziesz w artykule Tworzenie animacji za pomocą ObjectAnimator.

Dodaj ruch po krzywej

Chociaż użycie ObjectAnimator jest wygodne, domyślnie zmienia położenie widoku wzdłuż prostej linii między punktem początkowym i końcowym. Material Design opiera się na krzywych określających ruch przestrzenny obiektów na ekranie i czasie trwania animacji. Ruch po krzywej sprawia, że aplikacja nabiera bardziej materiału, a animacje stają się ciekawsze.

Określ własną ścieżkę

Klasa ObjectAnimator zawiera konstruktory umożliwiające animowanie współrzędnych przy użyciu co najmniej 2 właściwości naraz wraz ze ścieżką. Na przykład w tym animatorze do animacji właściwości X i Y widoku używa obiektu Path:

Kotlin

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    val path = Path().apply {
        arcTo(0f, 0f, 1000f, 1000f, 270f, -180f, true)
    }
    val animator = ObjectAnimator.ofFloat(view, View.X, View.Y, path).apply {
        duration = 2000
        start()
    }
} else {
    // Create animator without using curved path
}

Java

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  Path path = new Path();
  path.arcTo(0f, 0f, 1000f, 1000f, 270f, -180f, true);
  ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.X, View.Y, path);
  animator.setDuration(2000);
  animator.start();
} else {
  // Create animator without using curved path
}

Tak wygląda animacja łuku:

Rysunek 1. Animacja zakrzywionej ścieżki.

Interpolator to implementacja krzywej wygładzania. Więcej informacji o wygładzaniu krzywych znajdziesz w dokumentacji interfejsu Material Design. Interpolator określa sposób obliczania konkretnych wartości w animacji jako funkcji czasu. System udostępnia zasoby XML dla 3 podstawowych krzywych w specyfikacji Material Design:

  • @interpolator/fast_out_linear_in.xml
  • @interpolator/fast_out_slow_in.xml
  • @interpolator/linear_out_slow_in.xml

Używanie PathInterpolator

Klasa PathInterpolator to interpolator wprowadzony w Androidzie 5.0 (API 21). Opiera się na krzywej Beziera lub obiekcie Path. Przykłady dotyczące Androida w dokumentacji Material Design używają PathInterpolator.

PathInterpolator ma konstruktory oparte na różnych typach krzywych Béziera. Wszystkie krzywe Béziera mają odpowiednio punkty początkowy i końcowy: (0,0) i (1,1). Inne argumenty konstruktora zależą od typu tworzonej krzywej Béziera.

Na przykład w przypadku kwadratowej krzywej Béziera potrzebne są tylko współrzędne X i Y jednego punktu kontrolnego:

Kotlin

val myInterpolator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    PathInterpolator(0.67f, 0.33f)
} else {
    LinearInterpolator()
}

Java

Interpolator myInterpolator = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  myInterpolator = new PathInterpolator(0.67f, 0.33f);
} else {
  myInterpolator = new LinearInterpolator();
}

Powoduje to powstanie wygładzonej krzywej, która zaczyna się szybko i zwalnia, gdy zbliża się do końca.

Sześcienny konstruktor Bézier podobnie ma ustalony punkt początkowy i końcowy, ale wymaga dwóch punktów kontrolnych:

Kotlin

val myInterpolator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    PathInterpolator(0.5f, 0.7f, 0.1f, 1.0f)
} else {
    LinearInterpolator()
}

Java

Interpolator myInterpolator = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  myInterpolator = new PathInterpolator(0.5f, 0.7f, 0.1f, 1.0f);
} else {
  myInterpolator = new LinearInterpolator();
}

Jest to implementacja krzywej wygładzania z wyróżnieniem krzywej zwalniania w stylu Material Design.

Aby mieć większą kontrolę, możesz użyć dowolnego parametru Path do zdefiniowania krzywej:

Kotlin

val myInterpolator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  val path = Path().apply {
    moveTo(0.0f, 0.0f)
    cubicTo(0.5f, 0.7f, 0.1f, 1.0f, 1.0f, 1.0f)
  }
  PathInterpolator(path)
} else {
  LinearInterpolator()
}

Java

Interpolator myInterpolator = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  Path path = new Path();
  path.moveTo(0.0f, 0.0f);
  path.cubicTo(0.5f, 0.7f, 0.1f, 1.0f, 1.0f, 1.0f);
  myInterpolator = new PathInterpolator(path);
} else {
  myInterpolator = new LinearInterpolator();
}

W ten sposób powstaje taka sama krzywa wygładzania jak w przykładzie sześciennego Béziera, ale zamiast niej używana jest krzywa Path.

Interpolator ścieżki możesz też zdefiniować jako zasób XML:

<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
    android:controlX1="0.5"
    android:controlY1="0.7"
    android:controlX2="0.1f"
    android:controlY2="1.0f"/>

Po utworzeniu obiektu PathInterpolator możesz przekazać go do metody Animator.setInterpolator(). Animator używa interpolatora do określenia czasu lub krzywej ścieżki, gdy jest uruchamiana.

Kotlin

val animation = ObjectAnimator.ofFloat(view, "translationX", 100f).apply {
    interpolator = myInterpolator
    start()
}

Java

ObjectAnimator animation = ObjectAnimator.ofFloat(view, "translationX", 100f);
animation.setInterpolator(myInterpolator);
animation.start();