
みなさまこんにちは〜!
メモリアインクのすだです。
本日は、
KotlinのCompose Animations APIの「animate*AsState」関数を使って
アプリ画面にモダンなアニメーションを実装する方法を、
実際のコードを利用して徹底解説していきます!
この記事を読んでわかること…
・Compose Animations APIとは?
・Compose Animations APIを使用したアニメーションの実装方法
環境
- Kotlin (ver 1.9.0)
- Android Studio (Giraffe | 2022.3.1 Patch 3)
Compose Animations APIとは?
Compose Animations APIは、アニメーションを簡単かつ柔軟に作成するためのツールです。
モダンUIフレームワークであるJetpack Composeに統合されており、その中でも特にスムーズなアニメーションを宣言的に記述できます。
以下のような特徴があります。▼
- 宣言的UIに完全対応
- 状態に基づいたアニメーションの自動制御
- シンプルな構文で強力なカスタマイズが可能
また、今回はCompose Animations APIの特定の関数をご紹介しますが
Jetpack Composeは他にも数多くの便利なAPIを提供しています。
用途に応じて ぜひ調べて使ってみてください!
animate*AsStateとは?
animate*AsStateは、Compose Animations APIの一機能で
状態に応じてアニメーションを適用する最も基本的な方法です。
以下のように 型に応じた関数が様々に用意されています。▼
関数名 | 対象の型 | 用途 |
animateDpAsState | Dp | サイズや間隔、マージンのアニメーション |
animateFloatAsState | Float | 回転角度、透明度、スケールのアニメーション |
animateColorAsState | Color | 背景色やテキスト色のアニメーション |
animateIntAsState | Int | 数値やピクセルサイズのアニメーション |
animateOffsetAsState | Offset | 要素の移動や位置変更のアニメーション |
animateRectAsState | Rect | 矩形領域のアニメーション |
animateSizeAsState | Size | 要素全体の幅と高さのアニメーション |
animateIntOffsetAsState | IntOffset | 整数型の座標位置のアニメーション |
animateIntSizeAsState | IntSize | 整数型の幅と高さのアニメーションval size by animateIntSizeAsState(IntSize(300, 300)) |
UIの要件に応じて最適な関数を選択してください!
例として、いくつか実装してみましょう!
animate*AsStateを使った様々な実装
animateDpAsState: ボタンをクリックするとサイズが変化する実装
@Composable
fun SimpleDpAnimationExample() {
var isExpanded by remember { mutableStateOf(false) }
val size by animateDpAsState(targetValue = if (isExpanded) 200.dp else 100.dp)
Box(
modifier = Modifier
.size(size)
.background(Color.Blue)
.clickable { isExpanded = !isExpanded }
)
}
@Composable
は Jetpack Compose における Composable関数 を示すためのアノテーションです。
このアノテーションが付いた関数は、Jetpack ComposeのUIを構築するために使用されます。
3行目:
isExpanded
- ボックスが「拡大状態かどうか」を管理するフラグです。
remember
- Composeがこの状態をリメンバーし、再コンポーズ時も状態を保持します。
初期状態はfalse
(縮小状態)です。
- Composeがこの状態をリメンバーし、再コンポーズ時も状態を保持します。
4行目:
animateDpAsState
- 状態が変化するたびに、指定した値 (
targetValue
) に向けてスムーズにアニメーションします。 isExpanded
がtrue
のときは200.dp
、false
のときは100.dp
にアニメーションという実装です。
- 状態が変化するたびに、指定した値 (
6行目~:
Box
- 背景色を指定した四角形を描画するコンポーネントです。
Modifier.size(size)
- アニメーションで変化するサイズをここで適用します。
Modifier.clickable { isExpanded = !isExpanded }
- ボックスをクリックするたびに
isExpanded
を反転させます。
その結果として、サイズが縮小 (100.dp
) または拡大 (200.dp
) に切り替わります。
- ボックスをクリックするたびに
ビルドしてボタンを操作すると以下のようになります。


animateFloatAsState: ボタンをクリックすると回転する実装
@Composable
fun SimpleWidthAnimation() {
var isRotated by remember { mutableStateOf(false) }
// 2秒間で回転
val rotationAngle by animateFloatAsState(
targetValue = if (isRotated) 360f else 0f,
animationSpec = tween(
durationMillis = 2000, // アニメーションの時間(ミリ秒単位)
easing = LinearEasing // 等速で回転
)
)
Box(
modifier = Modifier
.size(100.dp)
.graphicsLayer(rotationZ = rotationAngle)
.background(Color.Blue)
.clickable {
isRotated = !isRotated
}
)
}
3行目:
isRotated
- 回転するかどうかの状態を管理するフラグ。初期値は
false
(回転していない状態)です。
- 回転するかどうかの状態を管理するフラグ。初期値は
6行目~:
animateFloatAsState
- 状態(
isRotated
)に応じて、回転角度(rotationAngle
)をアニメーションで変化させます。 - ターゲット値:
true
の場合: 360度(1回転)。false
の場合: 0度(元の位置)。
animationSpec
: アニメーションの動き方を設定します。tween
で 2000ミリ秒(2秒)かけて回転を行う。LinearEasing
を指定し、回転速度を一定にする。
- 状態(
15行目~:
graphicsLayer(rotationZ = rotationAngle)
- ボックスの Z軸(画面に対して垂直方向) を基準に回転させます。
rotationAngle
の値に応じて回転します。
clickable
- タップ操作で
isRotated
の値を切り替えます。
(状態が切り替わるたびに、アニメーションが発火)
- タップ操作で
ビルドしてボタンを操作すると以下のようになります。


(gifにするとなかなかわかりづらいですが、実際はきちんと回転しています)
animateIntAsState: ボタンをクリックすると幅が変化する実装
@Composable
fun SimpleWidthAnimation() {
var isExpanded by remember { mutableStateOf(false) }
val width by animateIntAsState(targetValue = if (isExpanded) 300 else 100)
Box(
modifier = Modifier
.height(100.dp)
.width(width.dp)
.background(Color.Green)
.clickable { isExpanded = !isExpanded }
)
}
3行目:
isExpanded
- ボックスが「拡大状態かどうか」を管理するフラグです。
remember
- Composeがこの状態をリメンバーし、再コンポーズ時も状態を保持します。
初期状態はfalse
(縮小状態)です。
- Composeがこの状態をリメンバーし、再コンポーズ時も状態を保持します。
4行目:
animateIntAsState
- isExpanded に基づいて、ボックスの幅(width)をアニメーションします。
- true の場合は幅が 300dp に、false の場合は幅が 100dp になります。
- 幅の変化がスムーズにアニメーションされます。
7行目~:
Modifier.width(width.dp)
- animateIntAsState で計算された幅を適用します。
Modifier.clickable { isExpanded = !isExpanded }
- ボックスをクリックするたびに isExpanded を反転させ、アニメーションをトリガーします。
ビルドしてボタンを操作すると以下のようになります。


まとめ
おつかれさまでした。いかがでしたでしょうか!
Compose Animations APIのanimate*AsState関数を活用すれば、シンプルなアニメーションから高度なカスタムアニメーションまで簡単に実現できます。
ぜひアプリ画面の実装に、役立ててくださいね〜!



技術者としてのキャリアパスを次のレベルへと進めたい皆様、
未経験からIT・Webエンジニアを目指すなら【ユニゾンキャリア】
自分の市場価値をさらに向上させてみませんか?
コメント