Najważniejsze
Interpolator — interfejs w Androidzie, który odwzorowuje ułamkową wartość postępu animacji (od 0.0 do 1.0) na rzeczywistą wartość ze zmienioną prędkością. Jeśli animacja trwa 300 milisekund, system wywołuje Interpolator dla każdej klatki, przekazując bieżący postęp. Interpolator zwraca zmodyfikowaną wartość — na przykład dla AccelerateInterpolator w 50% czasu animacja przechodzi jedynie ~25% drogi, symulując przyspieszenie.
Matematycznie Interpolator można przedstawić jako funkcję f(t), gdzie t to znormalizowany czas [0, 1], a f(t) to znormalizowana wartość [0, 1] (lub szersza dla Overshoot/Bounce). Liniowy interpolator zwraca f(t) = t — obiekt porusza się ze stałą prędkością. AccelerateInterpolator aproksymuje f(t) = t², DecelerateInterpolator — f(t) = 1 − (1 − t)², tworząc płynny start lub zakończenie. W Android Animation Framework Interpolator jest stosowany zarówno do ValueAnimator, jak i do ObjectAnimator oraz ViewPropertyAnimator, co daje jednolite podejście do zarządzania prędkością na wszystkich poziomach.
Android oferuje 9 wbudowanych interpolatorów, każdy z własnym modelem matematycznym. Wybór interpolatora określa charakter animacji: fizyczność (Bounce), sprężystość (Overshoot) lub płynność (AccelerateDecelerate).
| Interpolator | Matematyka | Scenariusz |
|---|---|---|
| LinearInterpolator | f(t) = t | Wskaźniki postępu, pasek przewijania |
| AccelerateInterpolator | f(t) = tⁿ (n=2) | Wylot elementu poza ekran, pojawianie się od dołu |
| DecelerateInterpolator | f(t) = 1 − (1 − t)ⁿ | Spadanie obiektu, wjazd z góry ze zwolnieniem |
| AccelerateDecelerateInterpolator | Aproksymacja cos | Uniwersalny, pojawianie/znikanie elementów |
| AnticipateInterpolator | Sześcienna z odrzutem wstecz | Sprężyste wejście — obiekt lekko odjeżdża przed startem |
| OvershootInterpolator | Sześcienna z przelotem | Przycisk akcji — lekko przeskakuje docelową pozycję |
| AnticipateOvershootInterpolator | Kombinacja Anticipate + Overshoot | Karty — odrzut wstecz + przelot z powrotem |
| BounceInterpolator | Tłumione odbicia | Piłka, spadanie elementu na powierzchnię |
| PathInterpolator | Bézier sześcienny (2 punkty kontrolne) | Niestandardowe krzywe dla systemu projektowania |
Każdy interpolator ma deklarację XML w res/interpolator/ i klasę Kotlin w pakiecie android.view.animation. AccelerateDecelerateInterpolator — najczęściej używany: jego krzywa przypomina funkcję easing ease-in-out w CSS. W aplikacjach Android z Material Design zaleca się OvershootInterpolator dla przycisków floating action button (FAB) — tworzy efekt „podskakiwania" przy pojawianiu się.
PathInterpolator — interpolator oparty na krzywej Béziera, zdefiniowany przez obiekt Path. Dostępny od API 21 (Android 5.0). Pozwala wizualnie zaprojektować krzywą prędkości — projektant rysuje krzywą, programista przenosi ją do kodu przez współrzędne punktów kontrolnych. Obsługiwany jest tylko sześcienny Bézier (dwa punkty kontrolne C1, C2).
Krzywa PathInterpolator zawsze zaczyna się w punkcie (0,0) i kończy w (1,1). Punkty kontrolne określają kształt: (x1, y1) — punkt na początku, (x2, y2) — na końcu. Wartości x muszą być w zakresie [0,1] — gwarantuje to monotoniczność w czasie. Wartości y mogą wychodzić poza [0,1] — tworzy to efekt przelotu (overshoot) lub odrzutu (anticipate). Na przykład standardowy Material Design używa krzywej fast-out-slow-in z punktami kontrolnymi (0.4, 0.0, 0.2, 1.0). W IT Sectr budujemy niestandardowe PathInterpolator dla każdego systemu projektowania — gwarantuje to jednolitość animacji na wszystkich ekranach.
Jeśli wbudowane interpolatory nie pokrywają scenariusza, Android pozwala stworzyć własny poprzez implementację interfejsu TimeInterpolator. Jedyna metoda — getInterpolation(input: Float): Float. Input — bieżący postęp animacji od 0 do 1; output — zmodyfikowana wartość. Output może wychodzić poza [0,1] dla efektów przelotu lub odbicia.
Typowe niestandardowe interpolatory: efekt bounce z tłumieniem (wyjście poza 1.0 i powrót), efekt elastic (sinusoidalne tłumienie), step-interpolator (dyskretne skoki). Niestandardowe interpolatory można również zdefiniować przez XML za pomocą tagu <interpolator> i podania klasy. W Android Studio jest wbudowany podgląd Interpolator w Layout Inspector — pokazuje rzeczywistą krzywą dla wybranego interpolatora, co ułatwia debugowanie.
Podstawowa animacja skali przycisku z użyciem symetrycznego interpolatora. ValueAnimator zmienia wartość od 1.0 do 1.2 i z powrotem, a AccelerateDecelerateInterpolator sprawia, że ruch jest płynny.
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 tworzy płynne zwiększenie na początku i płynny powrót na końcu. Metoda REVERSE powtarza animację w odwrotnym kierunku, tworząc efekt pulsacji. Ten wzorzec jest używany dla przycisków akcji, przyciągając uwagę użytkownika do kluczowego elementu interfejsu.
Niestandardowa krzywa z efektem overshoot — obiekt przelatuje docelową pozycję o 10% i wraca. Punkty kontrolne (0.4, 0.0, 0.6, 1.3) określają przyspieszony start z przelotem.
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 przyjmuje Path z sześcienną krzywą Béziera. W przykładzie element „przelatuje" docelową pozycję (y=1.3 w 60% czasu) i wraca do finału. Path musi być ściśle monotoniczny względem osi x, w przeciwnym razie animacja pójdzie do tyłu. Do weryfikacji użyj Layout Inspector w Android Studio.
Własny interpolator z efektem tłumionych odbić. Implementacja przez TimeInterpolator z czterema cyklami tłumienia.
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)
}
}
Niestandardowy DampedBounceInterpolator tworzy 4 tłumione odbicia ze współczynnikiem tłumienia 0.85. Metoda getInterpolation przyjmuje liniowy input i zwraca wartość z efektem „sprężyny". W IT Sectr używamy tego interpolatora do animacji pojawiania się powiadomień — odbicie tworzy wrażenie fizyczności i przyciąga uwagę.
Często zadawane pytania
AccelerateDecelerateInterpolator tworzy symetryczną krzywą — obiekt przyspiesza na początku i zwalnia na końcu. PathInterpolator pozwala zdefiniować dowolną krzywą przez Path z punktem kontrolnym (sześcienny Bézier). Do niestandardowej animacji z asymetrycznym zachowaniem (np. szybki start + wolne zakończenie) użyj PathInterpolator z punktami kontrolnymi (0.2, 0.8, 0.4, 1.0).
Tak, zaimplementuj interfejs TimeInterpolator i nadpisz metodę getInterpolation(input: Float): Float. Input — ułamkowa wartość od 0 do 1 (postęp animacji), output — rzeczywista wartość. Na przykład efekt bounce realizuje się przez zwracanie wartości większych niż 1 lub mniejszych niż 0 dla sprężystego zachowania. Zarejestruj interpolator przez XML-tag
PathInterpolator został dodany w API 21 (Android 5.0 Lollipop). Dla starszych wersji użyj AccelerateDecelerateInterpolator lub niestandardowego TimeInterpolator. PathInterpolator obsługuje tylko sześcienne krzywe Béziera z dwoma punktami kontrolnymi — linie proste i krzywe kwadratowe mogą dać nieprawidłową interpolację. Dla wstecznej kompatybilności użyj AccelerateDecelerateInterpolator jako fallback.
Material Design 3 zaleca krzywą fast-out-slow-in z punktami kontrolnymi (0.4, 0.0, 0.2, 1.0) do pojawiania się elementów, linear-out-slow-in (0.0, 0.0, 0.2, 1.0) do znikania i fast-out-linear-in (0.4, 0.0, 1.0, 1.0) do ruchu. W Androidzie te krzywe są zaimplementowane w klasie FastOutSlowInInterpolator z biblioteki Material Components.
Minimalnie. Wbudowane interpolatory wykonują jedną operację matematyczną na klatkę — narzut jest niezauważalny. Niestandardowe interpolatory z ciężkimi obliczeniami (trygonometria, pętle) mogą powodować micro-jank na słabych urządzeniach. Optymalizuj przez wstępne obliczanie wartości w konstruktorze lub używaj TimeInterpolator z buforowaniem.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również