Головне
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) | Вилiт елемента за межі екрану, поява знизу |
| 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 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також