Jetpcak composeでアニメーション

今回はJetpack composeでアニメーションのプログラムに挑戦してみました! といっても文字列を1文字ずつ移動させる程度のアニメーションですが、 実現したいことをどのように実装すれば良いのかイメージするのが難しかったです。 開発環境はAndroid Studio Giraffe(2022.3.1)を利用しています。

※この記事は2024/04/21時点の情報です。

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でアニメーションできました

今回のアニメーションを何かに利用することは無いと思いますが、何となく考え方は分かった気がします。 発想次第で素敵なアニメーションを作成することができるかも知れませんね。

さて、Jetpack composeでアニメーションを実装するイメージができましたか?

Jetpack composeのアニメーションを覚えられましたか?

よく分からなかった人は自分が実現したいアニメーションがどういう動きをするのかをイメージし、 少しずつ動かしながら試してみると良いかも知れません。

管理人情報