やりたいこと/できること
Webサイトなどでよく見かける「加速したあと減速するカウント(下記動画を見ていただいたほうが分かりやすいと思います)」をAndroidでも実装する方法について説明します。
サンプルとして、ボタンを押すと各Interpolator(下記解説)に応じたカウントアップアニメーションを開始する内容を実装します。
環境
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 | 開始から加速していき途中で減速 | |
AccelerateInterpolator | ゆっくりと開始し、その後に加速 | |
AnticipateInterpolator | 変化が逆方向に開始してから、順方向に切り替わる | |
AnticipateOvershootInterpolator | 変化が逆方向に開始し、順方向に切り替わり、目標値を過ぎてから終了値に戻る | |
BounceInterpolator | 終了値に向かってバウンドする(ボールが跳ね返るイメージ) | |
CycleInterpolator | 指定したサイクル数だけ逆方向と順方向に切り替わる | |
DecelerateInterpolator | 変化が急速に開始し減速 | |
LinearInterpolator | 変化の速度が一定 | |
OvershootInterpolator | 変化が順方向に開始し、最終値を過ぎてから戻る |
カウントアップ/ダウンでよく使うのは
AccelerateDecelerateInterpolator()
AccelerateInterpolator()
DecelerateInterpolator()
LinearInterpolator()
あたりでしょうか🤔
まとめ
- 値の変化にアニメーションをつけるにはValueAnimationを使う
- Interpolatorを指定することで様々なアニメーションへカスタマイズが可能
今までAndroidのアニメーションはMotionLayoutしか使ったことがなく、今回このサンプルを作るにあたって初めてアニメーションについて調べるキッカケになりました。今回はValueAnimationという昔からある技術を使いましたが、今後はJetpackComposeで提供されているアニメーションAPIを使って様々なアニメーションにチャレンジしてみたいと思います。
おまけ
文字のアルファ値もアニメーションして終了値に向かうに連れ濃くなるようにしてみました。(診断アプリとかに使えそう?)