Перемещение вида с помощью анимации

Попробуйте способ создания
Jetpack Compose — рекомендуемый набор инструментов пользовательского интерфейса для Android. Узнайте, как использовать анимацию в Compose.

Объекты на экране часто необходимо перемещать из-за взаимодействия с пользователем или скрытой обработки. Вместо немедленного обновления положения объекта, заставляющего его мигать из одной области в другую, используйте анимацию, чтобы переместить его из начальной позиции в конечную.

Один из способов, с помощью которого Android позволяет изменять положение объектов просмотра на экране, — это использование ObjectAnimator . Вы указываете конечную позицию, в которой должен расположиться объект, а также продолжительность анимации. Вы также можете использовать интерполяторы времени для управления ускорением или замедлением анимации.

Измените положение просмотра с помощью ObjectAnimator

API ObjectAnimator предоставляет возможность изменять свойства представления с указанной продолжительностью. Он содержит статические методы для создания экземпляров ObjectAnimator в зависимости от типа атрибута, который вы анимируете. При изменении положения представлений на экране используйте атрибуты translationX и translationY .

Вот пример ObjectAnimator , который перемещает вид в положение на 100 пикселей слева от экрана за 2 секунды:

Котлин

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

Ява

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

В этом примере используется метод ObjectAnimator.ofFloat() , поскольку значения перевода должны быть числами с плавающей запятой. Первый параметр — это вид, который вы хотите анимировать. Второй параметр — это свойство, которое вы анимируете. Поскольку представление должно перемещаться по горизонтали, используется свойство translationX . Последний параметр — это конечное значение анимации. В этом примере значение 100 указывает на позицию, находящуюся во многих пикселях от левой части экрана.

Следующий метод указывает, сколько времени занимает анимация (в миллисекундах). В этом примере анимация длится 2 секунды (2000 миллисекунд).

Последний метод вызывает запуск анимации, которая обновляет положение представления на экране.

Дополнительные сведения об использовании ObjectAnimator см. в разделе Animate с использованием ObjectAnimator .

Добавьте изогнутое движение

Хотя использование ObjectAnimator удобно, по умолчанию он перемещает вид по прямой между начальной и конечной точками. Материальный дизайн опирается на кривые для пространственного перемещения объектов на экране и синхронизации анимации. Использование изогнутого движения придает вашему приложению более материальный вид, а анимацию делает более интересной.

Определите свой собственный путь

Класс ObjectAnimator имеет конструкторы, которые позволяют анимировать координаты, используя одновременно два или более свойств вместе с путем. Например, следующий аниматор использует объект Path для анимации свойств X и Y представления:

Котлин

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
}

Ява

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
}

Вот как выглядит анимация дуги:

Рисунок 1. Анимация изогнутого пути.

Interpolator — это реализация кривой замедления. Дополнительную информацию о концепции кривых замедления см. в документации Material Design . Interpolator определяет, как определенные значения в анимации рассчитываются как функция времени. Система предоставляет ресурсы XML для трех основных кривых спецификации Material Design:

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

Используйте PathInterpolator

Класс PathInterpolator — это интерполятор, представленный в Android 5.0 (API 21). Он основан на кривой Безье или объекте Path . В примерах Android в документации Material Design для упрощения используется PathInterpolator .

PathInterpolator имеет конструкторы, основанные на различных типах кривых Безье. Все кривые Безье имеют начальную и конечную точки, фиксированные в (0,0) и (1,1) соответственно. Остальные аргументы конструктора зависят от типа создаваемой кривой Безье.

Например, для квадратичной кривой Безье необходимы только координаты X и Y одной контрольной точки:

Котлин

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

Ява

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

Это создает кривую замедления, которая начинается быстро и замедляется по мере приближения к концу.

Кубический конструктор Безье также имеет фиксированные начальную и конечную точки, но для него требуются две контрольные точки:

Котлин

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

Ява

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

Это реализация Material Design с акцентом на кривую замедления замедления .

Для большего контроля можно использовать произвольный Path для определения кривой:

Котлин

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

Ява

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

Это создает ту же кривую замедления, что и пример кубического Безье, но вместо этого используется Path .

Вы также можете определить интерполятор пути как ресурс 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"/>

Создав объект PathInterpolator , вы можете передать его методу Animator.setInterpolator() . Animator использует интерполятор для определения времени или кривой пути при запуске.

Котлин

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

Ява

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