Основни точки
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 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също