Jetpcak composeでアニメーション
今回はJetpack composeでアニメーションのプログラムに挑戦してみました! といっても文字列を1文字ずつ移動させる程度のアニメーションですが、 実現したいことをどのように実装すれば良いのかイメージするのが難しかったです。 開発環境はAndroid Studio Giraffe(2022.3.1)を利用しています。
MainActivity.kt
このコードは、AndroidアプリでComposeを使用してアニメーションを実装しています。
具体的には、各文字をAnimatedCharacter()メソッドの中で、Animatableを使用して
縦方向のoffsetYをアニメーションさせています。
実行すると画面の上部に「ポンコツ2人組」の文字が表示され、1文字ずつ下に移動→上に移動を繰り返します。
package com.example.animation
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.offset
import androidx.compose.ui.Modifier
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.animation.core.*
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.*
import androidx.compose.ui.unit.times
import com.example.animation.ui.theme.AnimationTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
AnimationTheme {
// A surface container using the 'background' color from the theme
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
AnimatedText()
}
}
}
}
}
@Composable
fun AnimatedText() {
val text = "ポンコツ2人組"
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.TopStart
) {
text.forEachIndexed { index, char ->
AnimatedCharacter(char, index)
}
}
}
@Composable
fun AnimatedCharacter(char: Char, index: Int) {
var offsetY by remember { mutableStateOf(0f) }
val animatableOffsetY = remember { Animatable(0f) }
LaunchedEffect(Unit) {
animatableOffsetY.animateTo(
targetValue = index * 30f,
animationSpec = infiniteRepeatable(
animation = tween(durationMillis = 500, delayMillis = index * 100),
repeatMode = RepeatMode.Reverse
)
)
}
LaunchedEffect(animatableOffsetY.value) {
offsetY = animatableOffsetY.value
}
Box(
modifier = Modifier.offset(y = offsetY.dp, x = index * 30.dp),
contentAlignment = Alignment.Center
) {
Text(
text = char.toString(),
style = TextStyle(fontSize = 24.sp),
textAlign = TextAlign.Center,
modifier = Modifier.align(Alignment.Center)
)
}
}
処理結果は次の通りです。 ※静止画像なので分かりにくいですが、文字が上下に移動しています。
今回のアニメーションを何かに利用することは無いと思いますが、何となく考え方は分かった気がします。 発想次第で素敵なアニメーションを作成することができるかも知れませんね。
さて、Jetpack composeでアニメーションを実装するイメージができましたか?
よく分からなかった人は自分が実現したいアニメーションがどういう動きをするのかをイメージし、 少しずつ動かしながら試してみると良いかも知れません。