Главное
Interpolator — интерфейс в Android, который отображает дробное значение хода анимации (от 0.0 до 1.0) в фактическое значение с изменённой скоростью. Если анимация длится 300 миллисекунд, система вызывает Interpolator для каждого кадра, передавая текущий прогресс. Interpolator возвращает модифицированное значение — например, для AccelerateInterpolator на 50% времени анимация проходит лишь ~25% пути, имитируя разгон.
Математически Interpolator можно представить как функцию f(t), где t — нормализованное время [0, 1], а f(t) — нормализованное значение [0, 1] (или шире для Overshoot/Bounce). Линейный интерполятор возвращает f(t) = t — объект движется с постоянной скоростью. AccelerateInterpolator аппроксимирует f(t) = t², DecelerateInterpolator — f(t) = 1 − (1 − t)², создавая плавное начало или завершение. В Android Animation Framework Interpolator применяется как к ValueAnimator, так и к ObjectAnimator и ViewPropertyAnimator, что даёт единый подход к управлению скоростью на всех уровнях.
Android предлагает 9 встроенных интерполяторов, каждый со своей математической моделью. Выбор интерполятора определяет характер анимации: физичность (Bounce), упругость (Overshoot) или плавность (AccelerateDecelerate).
| Интерполятор | Математика | Сценарий |
|---|---|---|
| LinearInterpolator | f(t) = t | Индикаторы прогресса, бегущая строка |
| AccelerateInterpolator | f(t) = tⁿ (n=2) | Вылет элемента за пределы экрана, появление снизу |
| DecelerateInterpolator | f(t) = 1 − (1 − t)ⁿ | Падение объекта, въезд сверху с замедлением |
| AccelerateDecelerateInterpolator | cos-аппроксимация | Универсальный, появление/исчезновение элементов |
| AnticipateInterpolator | Кубическая с откатом назад | Пружинистый вход — объект чуть отъезжает перед стартом |
| OvershootInterpolator | Кубическая с перелётом | Кнопка действия — чуть перескакивает целевую позицию |
| AnticipateOvershootInterpolator | Комбинация Anticipate + Overshoot | Карточки — откат назад + перелёт с возвратом |
| BounceInterpolator | Затухающие отскоки | Мяч, падение элемента на поверхность |
| PathInterpolator | Кубическая Безье (2 контрольные точки) | Кастомные кривые под дизайн-систему |
Каждый интерполятор имеет XML-декларацию в res/interpolator/ и Kotlin-класс в пакете android.view.animation. AccelerateDecelerateInterpolator — наиболее часто используемый: его кривая напоминает easing-функцию ease-in-out в CSS. Для Android-приложений с Material Design рекомендуется OvershootInterpolator для кнопок floating action button (FAB) — он создаёт эффект «подпрыгивания» при появлении.
PathInterpolator — интерполятор на основе кривой Безье, заданный через объект Path. Доступен с API 21 (Android 5.0). Позволяет визуально спроектировать кривую скорости — дизайнер рисует кривую, разработчик переносит её в код через координаты контрольных точек. Поддерживается только кубическая Безье (две контрольные точки C1, C2).
Кривая PathInterpolator всегда начинается в точке (0,0) и заканчивается в (1,1). Контрольные точки определяют форму: (x1, y1) — точка в начале, (x2, y2) — в конце. Значения x должны быть в диапазоне [0,1] — это гарантирует монотонность по времени. Значения y могут выходить за [0,1] — это создаёт эффект перелёта (overshoot) или отката (anticipate). Например, стандартный Material Design использует кривую fast-out-slow-in с контрольными точками (0.4, 0.0, 0.2, 1.0). В IT Sectr мы строим кастомные PathInterpolator под каждую дизайн-систему — это гарантирует единообразие анимаций во всех экранах.
Если встроенные интерполяторы не покрывают сценарий, Android позволяет создать собственный через реализацию интерфейса TimeInterpolator. Единственный метод — getInterpolation(input: Float): Float. Input — текущий прогресс анимации от 0 до 1; output — модифицированное значение. Output может выходить за [0,1] для эффектов перелёта или отскока.
Типичные кастомные интерполяторы: bounce-эффект с затуханием (выход за 1.0 и возврат), elastic-эффект (синусоидальное затухание), step-интерполятор (дискретные скачки). Кастомные интерполяторы можно также задать через XML с помощью тега <interpolator> и указания класса. В Android Studio есть встроенный превью Interpolator в Layout Inspector — он показывает реальную кривую для выбранного интерполятора, что упрощает отладку.
Базовая анимация масштаба кнопки с использованием симметричного интерполятора. ValueAnimator изменяет значение от 1.0 до 1.2 и обратно, а AccelerateDecelerateInterpolator делает движение плавным.
import android.animation.ValueAnimator
import android.view.animation.AccelerateDecelerateInterpolator
import android.view.View
fun View.pulseAnimation() {
ValueAnimator.ofFloat(1.0f, 1.2f).apply {
duration = 300
interpolator = AccelerateDecelerateInterpolator()
repeatCount = 1
repeatMode = ValueAnimator.REVERSE
addUpdateListener { animator ->
val scale = animator.animatedValue as Float
this@pulseAnimation.scaleX = scale
this@pulseAnimation.scaleY = scale
}
start()
}
}
AccelerateDecelerateInterpolator создаёт плавное увеличение в начале и плавное возвращение в конце. Метод REVERSE повторяет анимацию в обратном направлении, создавая эффект пульсации. Этот паттерн используется для кнопок действий, привлекая внимание пользователя к ключевому элементу интерфейса.
Кастомная кривая с эффектом overshoot — объект перелетает целевую позицию на 10% и возвращается. Контрольные точки (0.4, 0.0, 0.6, 1.3) задают ускоренный вход с перелётом.
import android.animation.ObjectAnimator
import android.graphics.Path
import android.view.animation.PathInterpolator
import android.view.View
fun View.slideWithOvershoot() {
val path = Path().apply {
cubicTo(0.4f, 0.0f, 0.6f, 1.3f, 1.0f, 1.0f)
}
val interpolator = PathInterpolator(path)
ObjectAnimator.ofFloat(this, "translationY", 200f, 0f).apply {
duration = 400
interpolator = interpolator
start()
}
}
PathInterpolator принимает Path с кубической кривой Безье. В примере элемент «перелетает» целевую позицию (y=1.3 на 60% времени) и возвращается к финалу. Path должен быть строго монотонным по оси x, иначе анимация пойдёт назад. Для проверки используйте Layout Inspector в Android Studio.
Собственный интерполятор с эффектом затухающих отскоков. Реализация через TimeInterpolator с четырьмя циклами затухания.
import android.animation.TimeInterpolator
class DampedBounceInterpolator : TimeInterpolator {
private val cycles = 4
private val damping = 0.85f
override fun getInterpolation(input: Float): Float {
val t = input * cycles
val decay = Math.pow(damping.toDouble(), cycles.toDouble()).toFloat()
val peak = t - (Math.floor(t.toDouble())).toFloat()
val bounce = Math.sin(peak * Math.PI).toFloat()
return 1f - bounce * decay * (1f - input)
}
}
Кастомный DampedBounceInterpolator создаёт 4 затухающих отскока с коэффициентом демпфирования 0.85. Метод getInterpolation принимает линейный input и возвращает значение с эффектом «пружины». В IT Sectr мы используем этот интерполятор для анимации появления уведомлений — отскок создаёт ощущение физичности и привлекает внимание.
Часто задаваемые вопросы
AccelerateDecelerateInterpolator создаёт симметричную кривую — объект ускоряется в начале и замедляется в конце. PathInterpolator позволяет задать произвольную кривую через Path с точкой управления (кубическая Безье). Для кастомной анимации с несимметричным поведением (например, быстрый старт + медленное завершение) используйте PathInterpolator с контрольными точками (0.2, 0.8, 0.4, 1.0).
Да, реализуйте интерфейс TimeInterpolator и переопределите метод getInterpolation(input: Float): Float. Input — дробное значение от 0 до 1 (ход анимации), output — фактическое значение. Например, bounce-эффект реализуется возвратом значений больше 1 или меньше 0 для пружинистого поведения. Зарегистрируйте интерполятор через XML-тег
PathInterpolator добавлен в API 21 (Android 5.0 Lollipop). Для старых версий используйте AccelerateDecelerateInterpolator или кастомный TimeInterpolator. PathInterpolator поддерживает только кубические кривые Безье с двумя контрольными точками — прямые линии и квадратичные кривые могут дать некорректную интерполяцию. Для обратной совместимости используйте AccelerateDecelerateInterpolator как fallback.
Material Design 3 рекомендует кривую fast-out-slow-in с контрольными точками (0.4, 0.0, 0.2, 1.0) для появления элементов, linear-out-slow-in (0.0, 0.0, 0.2, 1.0) для исчезновения и fast-out-linear-in (0.4, 0.0, 1.0, 1.0) для движения. В Android эти кривые реализованы в классе FastOutSlowInInterpolator из библиотеки Material Components.
Минимально. Встроенные интерполяторы выполняют одну математическую операцию на кадр — overhead незаметен. Кастомные интерполяторы с тяжёлыми вычислениями (тригонометрия, циклы) могут вызывать micro-jank на слабых устройствах. Оптимизируйте через предрасчёт значений в конструкторе или используйте TimeInterpolator с кэшированием.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также