Przenoszenie widoku za pomocą animacji

Wypróbuj metodę Compose
Jetpack Compose to zalecany zestaw narzędzi interfejsu na Androida. Dowiedz się, jak używać animacji w Compose.

Obiekty na ekranie często wymagają zmiany położenia ze względu na interakcję użytkownika lub przetwarzanie w tle. Zamiast natychmiast aktualizować pozycję obiektu, co powoduje miganie i przeskakiwanie z jednego obszaru do drugiego, użyj animacji, aby przenieść go z pozycji początkowej do końcowej.

Jednym ze sposobów, w jaki Android umożliwia zmianę położenia obiektów widoku na ekranie, jest użycie ObjectAnimator. Podajesz pozycję końcową, w której ma się zatrzymać obiekt, oraz czas trwania animacji. Możesz też używać interpolatorów czasu, aby kontrolować przyspieszanie lub zwalnianie animacji.

Zmiana pozycji widoku za pomocą klasy ObjectAnimator

Interfejs API ObjectAnimator umożliwia zmianę właściwości widoku w określonym czasie. Zawiera metody statyczne do tworzenia instancji klasy ObjectAnimator w zależności od typu animowanego atrybutu. Podczas zmiany położenia widoków na ekranie używaj atrybutów translationXtranslationY.

Oto przykład ObjectAnimator, który przesuwa widok do pozycji oddalonej o 100 pikseli od lewej krawędzi ekranu w ciągu 2 sekund:

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ć liczbami zmiennoprzecinkowymi. Pierwszy parametr to widok, który chcesz animować. Drugi parametr to właściwość, którą animujesz. 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 oznacza pozycję oddaloną o wiele pikseli od lewej strony ekranu.

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

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

Więcej informacji o używaniu ObjectAnimator znajdziesz w artykule Animowanie za pomocą klasy ObjectAnimator.

Dodawanie ruchu po łuku

Chociaż używanie funkcji ObjectAnimator jest wygodne, domyślnie zmienia ona położenie widoku wzdłuż linii prostej między punktami początkowym i końcowym. Material Design wykorzystuje krzywe do przestrzennego przemieszczania obiektów na ekranie i określania czasu trwania animacji. Użycie ruchu po łuku nadaje aplikacji bardziej materialny charakter, a animacje stają się ciekawsze.

Wyznacz własną ścieżkę

Klasa ObjectAnimator ma konstruktory, które umożliwiają animowanie współrzędnych za pomocą co najmniej 2 właściwości jednocześnie wzdłuż ścieżki. Na przykład ten animator używa obiektu Path do animowania właściwości X i Y widoku:

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
}

Animacja łuku wygląda tak:

Rysunek 1. Animacja przedstawiająca zakrzywioną ścieżkę.

Interpolator to implementacja krzywej wygładzania. Więcej informacji o krzywych łagodzenia znajdziesz w dokumentacji Material Design. Interpolatorokreśla, jak konkretne wartości w animacji są obliczane jako funkcja 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 klasy PathInterpolator

Klasa PathInterpolator to interpolator wprowadzony w Androidzie 5.0 (API 21). Jest on oparty na krzywej Béziera lub obiekcie Path. Przykłady na Androida w dokumentacji Material Design dotyczącej funkcji easinguPathInterpolator.

PathInterpolator ma konstruktory oparte na różnych typach krzywych Béziera. Wszystkie krzywe Béziera mają punkty początkowe i końcowe ustalone odpowiednio na (0,0)(1,1). Pozostałe 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();
}

Powstanie krzywa wygładzania, która zaczyna się szybko i zwalnia w miarę zbliżania się do końca.

Konstruktor krzywej Béziera trzeciego stopnia ma podobnie stałe punkty początkowe i końcowe, ale wymaga 2 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 łagodzenia emphasized decelerate w Material Design.

Aby mieć większą kontrolę, możesz użyć dowolnej wartości 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();
}

Daje to taką samą krzywą wygładzania jak w przypadku przykładu z krzywą Beziera trzeciego stopnia, ale zamiast niej używa funkcji 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ślania czasu lub ścieżki krzywej po uruchomieniu.

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();