Android Academy · レッスン

アニメーションが重要な理由

ユーザーを導き、操作を楽しませる動きを学びます。

レッスン 1/413 ステップ

「アニメーションが重要な理由」はCoddyKit上の無料Android Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAndroid Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Android Academyコースには全4レッスンが含まれています。

目的のあるモーション

アニメーションは単なる装飾ではありません。優れたAndroidアプリでは、モーションが注意を誘導し、何が変わったのかを説明し、UIを反応性が高く生き生きとしたものにします。

このコースでは、1行で使えるanimate*AsStateヘルパーからAnimatedVisibility、トランジション、物理ベースのスプリングまで、Jetpack ComposeのアニメーションAPIを学びます。

最初のレッスンでは、常に目的を持ってモーションを使えるように、アニメーションを使う理由とタイミングについて学びます。

Composeでは宣言的にアニメーションを使う

Composeでは、フレームごとにアニメーションを手動で開始・停止する必要はありません。代わりに目標値を記述すると、その値が変化したときにComposeが滑らかに目標値へアニメーションさせます。

ここでは、ボックスの色を1つのブール状態で制御しています。タップして状態を切り替えると、色が自動的に滑らかに変化します。

@Composable
fun ColorBox() {
    var selected by remember { mutableStateOf(false) }
    val color by animateColorAsState(
        targetValue = if (selected) Color.Green else Color.Gray,
        label = "box-color"
    )
    Box(
        Modifier
            .size(120.dp)
            .background(color)
            .clickable { selected = !selected }
    )
}

ユーザー操作へのフィードバック

モーションの最も重要な役割の1つがフィードバックです。ユーザーがボタンをタップしたりスイッチを切り替えたりしたとき、小さなアニメーションによってアプリが操作を受け付けたことを確認できます。

瞬間的でぎこちない変化は壊れたように感じられますが、150~300ミリ秒程度の短いトランジションは洗練された印象を与えます。ここでは、押している間だけボタンが少し縮みます。

@Composable
fun PressableButton(onClick: () -> Unit) {
    var pressed by remember { mutableStateOf(false) }
    val scale by animateFloatAsState(
        targetValue = if (pressed) 0.92f else 1f,
        label = "press-scale"
    )
    Button(
        onClick = onClick,
        modifier = Modifier.graphicsLayer {
            scaleX = scale; scaleY = scale
        }
    ) { Text("Tap me") }
}

状態の変化を説明する

UIが変化するとき、アニメーションはユーザーが何が起きたのかを理解するのに役立ちます。フェードしながらスライドインする要素は「新しく追加された」と伝わり、フェードアウトする要素は「削除された」と伝わります。

モーションがないと、コンテンツが突然現れたり消えたりするため、何かが表示されたのか、消えたのか、移動したのかをユーザーが理解できないことがあります。

@Composable
fun Banner(visible: Boolean) {
    AnimatedVisibility(
        visible = visible,
        enter = fadeIn() + slideInVertically(),
        exit = fadeOut() + slideOutVertically()
    ) {
        Text("Saved successfully!")
    }
}

連続性と空間感覚

モーションは連続性を保ちます。カードが展開したり要素が新しい位置に移動したりするとき、変化をアニメーションさせることで、ユーザーは画面上の位置関係を把握し続けられます。

Composeでは、Modifier.animateContentSize()を使ってレイアウトの変化を自動的にアニメーションできます。コンテンツが変化すると、ボックスが滑らかに拡大・縮小します。

@Composable
fun ExpandableCard(expanded: Boolean) {
    Column(
        Modifier
            .fillMaxWidth()
            .animateContentSize()
            .padding(16.dp)
    ) {
        Text("Title", style = MaterialTheme.typography.titleMedium)
        if (expanded) {
            Text("Here is the longer body that appears when expanded.")
        }
    }
}

期間とタイミングが重要

優れたアニメーションは高速です。ほとんどのUIトランジションは、およそ150~400ミリ秒に収めるべきです。遅すぎるとアプリが重く感じられ、速すぎると動きが見えません。

Composeでは、tweenとeasingカーブを使って、期間と速度の変化を調整できます。イージングによって加速と減速が生まれ、動きが自然に感じられます。

val offset by animateDpAsState(
    targetValue = if (open) 0.dp else 200.dp,
    animationSpec = tween(
        durationMillis = 300,
        easing = FastOutSlowInEasing
    ),
    label = "panel-offset"
)

やりすぎない

アニメーションは強力である一方、使いすぎやすい機能でもあります。モーションが多すぎると注意をそらし、ユーザーの操作を遅らせ、場合によっては不快感を引き起こします。

基本的な指針:

  • 装飾ではなく、伝達のためにアニメーションを使います。
  • トランジションは短く控えめにします。
  • 画面上のすべてを一度にアニメーションさせるのは避けます。
  • アニメーション中にユーザーの操作を妨げてはいけません。

アクセシビリティに配慮する

モーションに敏感なユーザーの中には、システム設定でアニメーションを減らすを有効にしている方もいます。配慮のあるアプリは、その設定を尊重します。

アニメーションの倍率がゼロに設定されているかどうかを読み取り、それに応じて重要でないモーションを減らしたり無効にしたりできます。

@Composable
fun rememberReduceMotion(): Boolean {
    val context = LocalContext.current
    val scale = Settings.Global.getFloat(
        context.contentResolver,
        Settings.Global.ANIMATOR_DURATION_SCALE,
        1f
    )
    return scale == 0f
}

Composeアニメーションツールボックス

Composeには、レイヤー構造になった複数のアニメーションAPIがあります。このコースでは、次のAPIを学びます。

  • animate*AsState - 単一の値(色、サイズ、浮動小数点数など)をアニメーションさせます。
  • AnimatedVisibility - 表示と非表示をアニメーションさせます。
  • updateTransition - 複数の値をまとめて調整します。
  • AnimatedContent - 異なるコンテンツ間をクロスフェードします。
  • Animatable と spring - 低レベルで物理ベースの制御を行います。

まずは高レベルAPIから始め、より細かな制御が必要になった場合だけ低レベルAPIを使ってください。

アニメーションは状態に従う

すべてを理解するための重要な考え方は、Composeではアニメーションが状態を追跡するということです。値を変更すると、アニメーションAPIが毎フレーム、UIを新しい値に向けて滑らかに補間します。

つまり、タイムラインを自分で記述することはほとんどありません。「このプロパティはXになるべき」と宣言すれば、Composeがその間のフレームを処理してくれます。

@Composable
fun FadingText(highlighted: Boolean) {
    val alpha by animateFloatAsState(
        targetValue = if (highlighted) 1f else 0.4f,
        label = "text-alpha"
    )
    Text(
        "Status",
        modifier = Modifier.graphicsLayer { this.alpha = alpha }
    )
}

純粋なKotlinで簡単な準備

アニメーションは値と値の間を補間します。その核心にあるのは単純な数学です。0から1までの分数 t を使って、開始値と終了値を混ぜ合わせます。この考え方(線形補間、つまり lerp)が、これから作成するすべてのアニメーションの基礎になります。

この小さな純粋なKotlinのスニペットは、Composeが1秒間に何度も適用している考え方を示しています。

fun lerp(start: Float, end: Float, t: Float): Float =
    start + (end - start) * t

fun main() {
    for (i in 0..4) {
        val t = i / 4f
        println("t=$t -> ${lerp(0f, 100f, t)}")
    }
}

確認問題

Jetpack Composeにおけるアニメーションの基本的な考え方は何ですか?

まとめ:意味のある動き

これで、アニメーションがなぜ重要なのか、そしてその背景にあるモデルを理解できました。

  • 動きはフィードバックを提供し、変化を説明し、連続性を保ちます。
  • Composeのアニメーションは宣言的で、状態に従います。
  • トランジションは短く(約150~400ミリ秒)、目的を持たせてください。使いすぎないことが大切です。
  • アクセシビリティのために動きを減らしているユーザーに配慮してください。
  • まずは高レベルAPIを使用してください。animate*AsState、AnimatedVisibility、トランジション、スプリングなどが該当します。

次は、animate*AsStateファミリーを使って単一の値をアニメーションさせます。

無料で開始

AI チューターと学ぶ Kotlin — 無料

ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。

コース
36
レッスン
152

よくある質問

「アニメーションが重要な理由」レッスンは無料ですか?

はい。「アニメーションが重要な理由」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Android Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Android Academyコースには全4レッスンが含まれています。

「アニメーションが重要な理由」で何を学びますか?

ユーザーを導き、操作を楽しませる動きを学びます。 ブラウザで直接実行するハンズオンコードでAndroid Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Android Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのAndroid Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「アニメーションが重要な理由」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このAndroid Academyレッスンでコードを書いて実行できますか?

はい。すべてのAndroid Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. アニメーションが重要な理由
  2. animate*AsStateの基本
  3. AnimatedVisibilityとトランジション
  4. ジェスチャーとスプリングアニメーション
← Android Academyに戻る