💫

ObjectAnimatorでいろいろなアニメーションを実装してみる

2021/12/19に公開

Androidでアニメーションを実装する方法として、プロパティアニメーションというフレームワークがあります。
今回はプロパティアニメーションのクラスの一つである、ObjectAnimatorを使っていろいろなアニメーションを実装してみました。

ObjectAnimatorの基本的な使い方

オブジェクトと、そのオブジェクトのプロパティの名前を(文字列として)指定し、アニメーション化する値の範囲も指定します。

ObjectAnimator.ofFloat(targetView, "translationX", 100f).apply {
    duration = 1000 // 1000msかけてアニメーションさせる
    interpolator = LinearInterpolator() // 変化の速度は一定
    start() // アニメーション開始
}

指定できるプロパティには相対的な変化量を指定してViewを移動させるtranslationX translationYや回転させるrotation、サイズを変更するscaleX scaleY、透過度を変化させるalphaなどがあります。

主なInterpolator

Interpolatorを指定することで、アニメーションを線形的に実行するか非線形的に実行するかなど様々なカスタマイズをすることができます。

クラス 説明
LinearInterpolator 変化の速度が一定であるInterpolator
AccelerateInterpolator 変化がゆっくりと開始し、その後に加速するInterpolator
DecelerateInterpolator 変化が急速に開始し、その後に減速するInterpolator
AccelerateDecelerateInterpolator 変化の速度が最初と最後で遅く、中間で加速するInterpolator
AnticipateInterpolator 変化が逆方向に開始してから、順方向に切り替わるInterpolator

アニメーションの例

1. フェードアウトさせる

fun View.startFadeoutAnim() {
    val animator = ObjectAnimator.ofFloat(this, View.ALPHA, 1.0f, 0.0f).apply {
        duration = 500
    }
    animator.start()
}

2. 無限ループで回転させる

fun View.startRotateAnim() {
    val animator = ObjectAnimator.ofFloat(this, View.ROTATION, 0f, 360f).apply {
        duration = 3000
        repeatCount = ObjectAnimator.INFINITE
    }
    animator.start()
}

3. 指定した変化量だけ移動させる

fun View.startMoveToPointAnim(transX: Float, transY: Float) {
    val translationX = PropertyValuesHolder.ofFloat(View.TRANSLATION_X, transX)
    val translationY = PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, transY)
    val animator = ObjectAnimator.ofPropertyValuesHolder(this, translationX, translationY).apply {
        duration = 500
        interpolator = DecelerateInterpolator() // 急速に開始し、その後減速しながら変化させる
    }
    animator.start()
}

4. 無限ループで拡大したり縮小させる

fun View.startInflateShrinkAnim() {
    val inflateX = PropertyValuesHolder.ofFloat(View.SCALE_X, 1.0f, 1.5f)
    val inflateY = PropertyValuesHolder.ofFloat(View.SCALE_Y, 1.0f, 1.5f)
    val animator = ObjectAnimator.ofPropertyValuesHolder(this, inflateX, inflateY).apply {
        duration = 1000
        repeatCount = ObjectAnimator.INFINITE
        repeatMode = ObjectAnimator.REVERSE
    }
    animator.start()
}

5. 拡大しながらフェードアウトさせる

fun View.startInflateFadeoutAnim() {
    val inflateX = PropertyValuesHolder.ofFloat(View.SCALE_X, 1.0f, 1.5f)
    val inflateY = PropertyValuesHolder.ofFloat(View.SCALE_Y, 1.0f, 1.5f)
    val fadeout = PropertyValuesHolder.ofFloat(View.ALPHA, 1.0f, 0.0f)
    val animator = ObjectAnimator.ofPropertyValuesHolder(this, inflateX, inflateY, fadeout).apply {
        duration = 500
    }
    animator.start()
}

アニメーションの制御

アニメーションの一時停止や再開も以下のようにすれば実行できます。

animator.pause() // アニメーションを一時停止する
animator.resume() // アニメーションを再開する

また、実行後や実行中のアニメーションの初期位置を復元したい場合はreverse()をすることでViewをアニメーション開始前の状態に復元することが可能です。

animator.apply {
    duration = 0 // 瞬時にアニメーションを実行
    reverse() // アニメーションを戻す
}

参考記事

https://developer.android.com/guide/topics/graphics/prop-animation?hl=ja

Discussion