3
3

More than 1 year has passed since last update.

【JetpackCompose】”いい感じの”カウントアップアニメーションを作ってみた

Last updated at Posted at 2022-09-25

やりたいこと/できること

Webサイトなどでよく見かける「加速したあと減速するカウント(下記動画を見ていただいたほうが分かりやすいと思います)」をAndroidでも実装する方法について説明します。
サンプルとして、ボタンを押すと各Interpolator(下記解説)に応じたカウントアップアニメーションを開始する内容を実装します。
sample_resize.gif

環境

material3 : 1.0.0-beta03
Kotlin : 1.7.0
JetpackCompose : 1.2.0

ソースコードと説明

ValueAnimationを使う

Androidには様々なアニメーションの種類がありますが、値の増減をアニメーションさせるためにはValueAnimationを使います。ValueAnimationではint、float、または color の値のセットを指定することで、アニメーションの継続時間中に値の増減にアニメーションをセットすることができます。

@Composable
fun CountUpScreen() {
    val initValue = 0
    val targetValue = 100
    val setDuration = 10000L // アニメーションの時間を10秒に設定
    val count = remember{ mutableStateOf(0) }

    val animator = ValueAnimator.ofInt(initValue, targetValue).apply{
        duration= setDuration
        interpolator= AccelerateDecelerateInterpolator()
        addUpdateListener{
            count.value =it.animatedValue as Int // アニメーションで更新された値をcountへ格納
        }
    }

    Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ){
        Text(
            text = "${count.value}",
            fontSize = 96.sp,
            fontWeight = FontWeight.Bold
        )
        Button(
            onClick ={animator.start()} // ボタンを押したらアニメーションスタート
        ){
            Text(text = "CountUp")
        }
    }

}

今回のサンプルでは以下のメソッドを使用しました。

  • ofInt():アニメーションで開始する値と終了値を設定
  • dulation:初期値から終了値へ変化するまでにかかる時間
  • interpolator:値の変化に対するアニメーションのタイプ(詳しくは以下の項目で解説)
  • start():アニメーションの実行
  • onAnimationUpdate():アニメーションで更新した値を取得し、countへ格納
    詳細な内容についてここでは割愛していますので、こちらのリファレンスをご参考ください。

Interpolatorでアニメーションの変化を制御する

アニメーションの変化を制御するにはInterpolatorを指定します。

デフォルトではAccelerateDecelerateInterpolator()が設定されており、以下の表に示したInterpolatorを設定することで、アニメーションに様々な変化をつけることができます。

動作 クラス/インターフェース 説明
AccelerateDecelerateInterpolator.gif AccelerateDecelerateInterpolator 開始から加速していき途中で減速
AccelerateInterpolator.gif AccelerateInterpolator ゆっくりと開始し、その後に加速
Anticipatepolator.gif AnticipateInterpolator 変化が逆方向に開始してから、順方向に切り替わる
AnticipateOvershootInterpolator.gif AnticipateOvershootInterpolator 変化が逆方向に開始し、順方向に切り替わり、目標値を過ぎてから終了値に戻る
BounceInterpolator.gif BounceInterpolator 終了値に向かってバウンドする(ボールが跳ね返るイメージ)
CycleInterpolator.gif CycleInterpolator 指定したサイクル数だけ逆方向と順方向に切り替わる
DecelerateInterpolator.gif DecelerateInterpolator 変化が急速に開始し減速
LinearInterpolator.gif LinearInterpolator 変化の速度が一定
OvershootInterpolator.gif OvershootInterpolator 変化が順方向に開始し、最終値を過ぎてから戻る

カウントアップ/ダウンでよく使うのは

  • AccelerateDecelerateInterpolator()
  • AccelerateInterpolator()
  • DecelerateInterpolator()
  • LinearInterpolator()

あたりでしょうか🤔

まとめ

  • 値の変化にアニメーションをつけるにはValueAnimationを使う
  • Interpolatorを指定することで様々なアニメーションへカスタマイズが可能

今までAndroidのアニメーションはMotionLayoutしか使ったことがなく、今回このサンプルを作るにあたって初めてアニメーションについて調べるキッカケになりました。今回はValueAnimationという昔からある技術を使いましたが、今後はJetpackComposeで提供されているアニメーションAPIを使って様々なアニメーションにチャレンジしてみたいと思います。

おまけ

文字のアルファ値もアニメーションして終了値に向かうに連れ濃くなるようにしてみました。(診断アプリとかに使えそう?)
omake.gif

参考

関連ドキュメント

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3