핵심 요점
Interpolator — Android의 인터페이스로, 애니메이션 진행의 분수 값(0.0~1.0)을 수정된 속도의 실제 값에 매핑합니다. 애니메이션이 300밀리초 동안 지속되면 시스템은 각 프레임에 대해 Interpolator를 호출하여 현재 진행률을 전달합니다. Interpolator는 수정된 값을 반환합니다. 예를 들어 AccelerateInterpolator를 사용하면 시간의 50%에서 애니메이션이 경로의 약 25%만 이동하여 가속을 시뮬레이션합니다.
수학적으로 Interpolator는 함수 f(t)로 표현할 수 있습니다. 여기서 t는 정규화된 시간 [0, 1]이고 f(t)는 정규화된 값 [0, 1](Overshoot/Bounce의 경우 더 넓음)입니다. LinearInterpolator는 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 | 후퇴가 있는 3차 | 탄성 진입 — 객체가 시작 전에 약간 뒤로 물러남 |
| OvershootInterpolator | 초과가 있는 3차 | 작업 버튼 — 목표 위치를 약간 초과함 |
| AnticipateOvershootInterpolator | Anticipate + Overshoot 조합 | 카드 — 후퇴 + 복귀와 함께 초과 |
| BounceInterpolator | 감쇠 바운스 | 공, 표면에 떨어지는 요소 |
| PathInterpolator | 3차 베지어(2개 제어점) | 디자인 시스템을 위한 사용자 정의 곡선 |
각 인터폴레이터에는 res/interpolator/에 XML 선언이 있고 android.view.animation 패키지에 Kotlin 클래스가 있습니다. AccelerateDecelerateInterpolator가 가장 자주 사용됩니다. 그 곡선은 CSS의 ease-in-out 이징 함수와 유사합니다. Material Design을 사용하는 Android 앱의 경우 플로팅 액션 버튼(FAB)에 OvershootInterpolator가 권장됩니다. 나타날 때 튕기는 효과를 만듭니다.
PathInterpolator — Path 객체를 통해 정의되는 베지어 곡선 기반 인터폴레이터입니다. API 21(Android 5.0)부터 사용 가능합니다. 속도 곡선을 시각적으로 설계할 수 있습니다. 디자이너가 곡선을 그리고 개발자가 제어점 좌표를 통해 코드로 변환합니다. 3차 베지어만 지원됩니다(두 개의 제어점 C1, C2).
PathInterpolator 곡선은 항상 점(0,0)에서 시작하여 (1,1)에서 끝납니다. 제어점이 모양을 정의합니다: (x1, y1) — 시작점, (x2, y2) — 끝점. x 값은 [0,1] 범위에 있어야 합니다. 이는 시간에 따른 단조성을 보장합니다. y 값은 [0,1]을 초과할 수 있습니다. 이는 초과 또는 예상 효과를 만듭니다. 예를 들어 표준 Material Design은 제어점(0.4, 0.0, 0.2, 1.0)으로 fast-out-slow-in 곡선을 사용합니다. IT Sectr에서는 각 디자인 시스템에 맞춤화된 PathInterpolator를 구축하여 모든 화면에서 일관된 애니메이션을 보장합니다.
내장 인터폴레이터가 시나리오를 커버하지 못하는 경우 Android에서는 TimeInterpolator 인터페이스를 구현하여 사용자 정의 인터폴레이터를 만들 수 있습니다. 유일한 메서드는 getInterpolation(input: Float): Float입니다. Input은 0에서 1까지의 현재 애니메이션 진행률이고 output은 수정된 값입니다. output은 초과 또는 바운스 효과를 위해 [0,1]을 벗어날 수 있습니다.
일반적인 사용자 정의 인터폴레이터: 감쇠 바운스 효과(1.0 초과 후 복귀), 탄성 효과(사인파 감쇠), 스텝 인터폴레이터(개별 점프). 사용자 정의 인터폴레이터는 <interpolator> 태그와 클래스를 지정하여 XML로도 정의할 수 있습니다. Android Studio의 Layout Inspector에는 내장 Interpolator 미리보기가 있어 선택한 인터폴레이터의 실제 곡선을 표시하여 디버깅을 간소화합니다.
대칭 인터폴레이터를 사용한 기본 버튼 스케일 애니메이션. 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 모드는 애니메이션을 반대 방향으로 반복하여 맥동 효과를 만듭니다. 이 패턴은 작업 버튼에 사용되어 사용자의 주의를 주요 인터페이스 요소로 끕니다.
초과 효과가 있는 사용자 정의 곡선 — 객체가 목표 위치를 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는 3차 베지어 곡선이 있는 Path를 받습니다. 예제에서 요소는 목표 위치(시간의 60%에서 y=1.3)를 초과하고 최종 위치로 돌아옵니다. Path는 x축을 따라 엄격하게 단조로워야 합니다. 그렇지 않으면 애니메이션이 거꾸로 진행됩니다. 확인을 위해 Android Studio의 Layout Inspector를 사용하세요.
감쇠 바운스 효과가 있는 사용자 정의 인터폴레이터. 4개의 감쇠 주기로 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는 감쇠 계수 0.85로 4번의 감쇠 바운스를 만듭니다. getInterpolation 메서드는 선형 입력을 받아 스프링 효과가 있는 값을 반환합니다. IT Sectr에서는 알림 표시 애니메이션에 이 인터폴레이터를 사용합니다. 바운스는 물리적 느낌을 만들고 주의를 끕니다.
자주 묻는 질문
AccelerateDecelerateInterpolator는 대칭 곡선을 만듭니다. 객체가 시작에서 가속되고 끝에서 감속됩니다. PathInterpolator는 제어점(3차 베지어)이 있는 Path를 통해 임의의 곡선을 지정할 수 있습니다. 비대칭 동작(예: 빠른 시작 + 느린 종료)의 사용자 정의 애니메이션의 경우 제어점(0.2, 0.8, 0.4, 1.0)으로 PathInterpolator를 사용하세요.
네, TimeInterpolator 인터페이스를 구현하고 getInterpolation(input: Float): Float 메서드를 재정의하세요. Input은 0에서 1까지의 분수 값(애니메이션 진행률)이고 output은 실제 값입니다. 예를 들어 스프링 같은 동작을 위해 1보다 크거나 0보다 작은 값을 반환하여 바운스 효과를 구현합니다. XML 태그
PathInterpolator는 API 21(Android 5.0 Lollipop)에서 추가되었습니다. 이전 버전의 경우 AccelerateDecelerateInterpolator 또는 사용자 정의 TimeInterpolator를 사용하세요. PathInterpolator는 두 개의 제어점이 있는 3차 베지어 곡선만 지원합니다. 직선과 2차 곡선은 잘못된 보간을 생성할 수 있습니다. 하위 호환성을 위해 폴백으로 AccelerateDecelerateInterpolator를 사용하세요.
Material Design 3은 요소 표시를 위해 제어점(0.4, 0.0, 0.2, 1.0)의 fast-out-slow-in 곡선, 숨김을 위해 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에서 이러한 곡선은 Material Components 라이브러리의 FastOutSlowInInterpolator 클래스에 구현되어 있습니다.
최소한입니다. 내장 인터폴레이터는 프레임당 하나의 수학 연산을 수행하므로 오버헤드가 무시할 수 있습니다. 무거운 계산(삼각법, 루프)이 있는 사용자 정의 인터폴레이터는 약한 기기에서 마이크로 잔상을 유발할 수 있습니다. 생성자에서 값을 미리 계산하거나 캐싱과 함께 TimeInterpolator를 사용하여 최적화하세요.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.