Przenoszenie widoku za pomocą animacji

Obiekty na ekranie często muszą zostać przemieszczone ze względu na interakcję użytkownika lub przetwarzanie w tle. Zamiast natychmiast aktualizować położenie obiektu, które powoduje miganie między obszarami, użyj animacji, która przeniesie go z pozycji początkowej do końcowej.

Jednym ze sposobów na zmiany położenia obiektów widoku na ekranie w Androidzie jest użycie narzędzia ObjectAnimator. Podajesz pozycję końcową, w której ma się znaleźć obiekt, oraz czas trwania animacji. Do sterowania przyspieszeniem i zwolnieniem animacji można też używać interpolatorów czasowych.

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 statyczne metody tworzenia instancji ObjectAnimator w zależności od typu animowanego atrybutu. Zmieniając położenie widoków na ekranie, używaj atrybutów translationX i translationY.

Oto przykład elementu ObjectAnimator, który w 2 sekundy przesuwa widok do pozycji o 100 pikseli od lewej strony 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 translacji muszą być liczbami zmiennoprzecinkowa. Pierwszy parametr to widok, który chcesz animować. Drugi parametr to animowana właściwość. Widok musi zostać przesunięty w poziomie, więc używana jest właściwość translationX. Ostatni parametr to wartość końcowa animacji. W tym przykładzie wartość 100 wskazuje pozycję 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 i zmianę pozycji widoku na ekranie.

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

Dodaj ruch zakrzywiony

ObjectAnimator jest wygodne, ale domyślnie zmienia położenie widoku wzdłuż linii prostej między punktem początkowym a końcowym. Material Design opiera się na krzywych przestrzennych przemieszczaniu się obiektów na ekranie oraz do określania momentu animacji. Dzięki korzystaniu z ruchu zakrzywionego aplikacja wydaje się bardziej realistyczna, a animacje staje się bardziej interesujące.

Zdefiniuj własną ścieżkę

Klasa ObjectAnimator ma konstruktory, które umożliwiają animowanie współrzędnych z wykorzystaniem co najmniej 2 właściwości jednocześnie ze ścieżką. 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
}

Oto jak wygląda animacja łuku:

Rysunek 1. Animacja zakrzywionej ścieżki.

Interpolator to implementacja krzywej wygładzania. Więcej informacji o wygładzeniu krzywych znajdziesz w dokumentacji Material Design. Interpolator określa sposób obliczania konkretnych wartości w animacji jako funkcji czasu. System udostępnia zasoby XML dotyczące 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żyj metody PathInterpolator

Klasa PathInterpolator to interpolator wprowadzony w Androidzie 5.0 (API 21). Opiera się na krzywej Beziera lub obiektu Path. W przykładach dotyczących Androida opisanych w dokumentacji Material Design dotyczącej wygładzania używamy PathInterpolator.

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

Na przykład w przypadku kwadratowej krzywej Beziera 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();
}

W ten sposób powstanie krzywa wygładzania, która zaczyna się szybko i spowalnia w miarę zbliżania się do końca.

Sześcienny konstruktor Béziera podobnie ma 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();
}

To jest implementacja krzywej wygładzania interfejsu Material Design ze zaznaczonym zwolnieniem.

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

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

Powoduje to utworzenie tej samej krzywej wygładzania co w przykładzie sześciennej funkcji Béziera, ale zamiast niej użyto funkcji Path.

Jako zasób XML możesz też zdefiniować interpolator ścieżki:

<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 go przekazać do metody Animator.setInterpolator(). Po uruchomieniu Animator używa interpolatora do określenia czasu lub krzywej ścieżki.

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