重要なポイント
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 | 引き戻し付き三次曲線 | バネのような開始 — オブジェクトが開始前に少し後退する |
| OvershootInterpolator | オーバーシュート付き三次曲線 | アクションボタン — ターゲット位置を少し超える |
| AnticipateOvershootInterpolator | Anticipate + Overshoot の組み合わせ | カード — 引き戻し + 戻りを伴うオーバーシュート |
| BounceInterpolator | 減衰バウンス | ボール、表面に落ちる要素 |
| PathInterpolator | 三次ベジェ(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)以降で使用可能です。速度曲線を視覚的に設計できます。デザイナーが曲線を描き、開発者が制御点の座標を通じてコードに変換します。サポートされるのは三次ベジェのみです(2 つの制御点 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 は三次ベジェ曲線を持つ 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 は、制御点(三次ベジェ)を持つ 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 は 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 クラスに実装されています。
最小限です。組み込みのインターポレータはフレームごとに 1 つの数学演算を実行するため、オーバーヘッドは無視できます。負荷の高い計算(三角関数、ループ)を含むカスタムインターポレータは、低性能デバイスでマイクロジャンクを引き起こす可能性があります。コンストラクタで値を事前計算するか、キャッシュを使用する TimeInterpolator を使用して最適化してください。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。