0Pricing
Android Academy · レッスン

AnimatedVisibilityとトランジション

コンテンツの表示と非表示をアニメーションさせます。

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

表示をアニメーションさせる

コンテンツが突然表示・非表示になると、不自然な印象を与えます。ComposeのAnimatedVisibilityは、コンポーザブルがレイアウトに入るときと出るときにアニメーションさせます。

コンテンツをこのAPIでラップし、ブール値で表示状態を制御します。ブール値が変わると、瞬時に切り替わる代わりに、Composeが表示または非表示のアニメーションを実行します。

@Composable
fun Greeting(show: Boolean) {
    AnimatedVisibility(visible = show) {
        Text("Welcome aboard!")
    }
}

表示・非表示のトランジション

enter パラメータと exit パラメータを使うと、コンテンツの表示と非表示の方法を細かく選べます。一般的な構成要素には、fadeIn/fadeOut、slideIn/slideOut、expandVertically/shrinkVertically などがあります。

+ 演算子で組み合わせると、複数のアニメーションを同時に実行できます。

@Composable
fun Toast(show: Boolean) {
    AnimatedVisibility(
        visible = show,
        enter = fadeIn() + slideInVertically { it },
        exit = fadeOut() + slideOutVertically { it }
    ) {
        Text("Item added to cart")
    }
}

トランジション仕様を調整する

各表示・非表示トランジションは animationSpec を受け取るため、animate*AsState と同じように、時間とイージングを制御できます。

ここではコンテンツが300ミリ秒かけてフェードインし、フェードアウトはより速い150ミリ秒で行われます。これは、閉じる操作をきびきびと感じさせる一般的なパターンです。

AnimatedVisibility(
    visible = show,
    enter = fadeIn(animationSpec = tween(300)),
    exit = fadeOut(animationSpec = tween(150))
) {
    Card { Text("Details") }
}

展開と縮小

より多くのコンテンツを表示するセクションでは、expandVertically と shrinkVertically を使って高さをアニメーションさせ、周囲のコンテンツを滑らかに押しのけます。

折りたたみ可能なパネル、FAQ項目、「もっと見る」セクションなどに最適です。

@Composable
fun Details(expanded: Boolean) {
    AnimatedVisibility(
        visible = expanded,
        enter = expandVertically() + fadeIn(),
        exit = shrinkVertically() + fadeOut()
    ) {
        Text("Extra details revealed when expanded.")
    }
}

updateTransition:1つの状態から複数の値を制御する

1つの状態に応じて複数のプロパティを一緒に変更する場合、updateTransition がそれらを調整します。子要素がすべて同期してアニメーションする Transition オブジェクトを作成します。

状態を定義し、その状態に応じた各プロパティの関数として、animateColor、animateDp などを使用します。

enum class BoxState { Collapsed, Expanded }

@Composable
fun MorphingBox(state: BoxState) {
    val transition = updateTransition(state, label = "box")
    val size by transition.animateDp(label = "size") {
        if (it == BoxState.Expanded) 200.dp else 100.dp
    }
    val color by transition.animateColor(label = "color") {
        if (it == BoxState.Expanded) Color.Magenta else Color.Cyan
    }
    Box(Modifier.size(size).background(color))
}

トランジションでプロパティごとにタイミングを設定する

updateTransition の大きな利点は、プロパティごとにタイミングを設定できることです。それぞれの animate* 子要素に独自の transitionSpec を指定できるため、同じ状態によって調整しながら、色とサイズを異なる速度で変化させられます。

val size by transition.animateDp(
    transitionSpec = { tween(durationMillis = 300) },
    label = "size"
) { if (it == BoxState.Expanded) 200.dp else 100.dp }

val corner by transition.animateDp(
    transitionSpec = { tween(durationMillis = 600) },
    label = "corner"
) { if (it == BoxState.Expanded) 0.dp else 24.dp }

AnimatedContent:コンテンツを切り替える

表示状態だけでなく、コンテンツ自体が変化する場合は AnimatedContent を使用します。古いコンテンツと新しいコンテンツの間をアニメーションさせ、デフォルトではクロスフェードします。

カウンター、ステップインジケーター、読み込み中と読み込み完了の状態の切り替えなどに適しています。

@Composable
fun Counter(count: Int) {
    AnimatedContent(
        targetState = count,
        label = "counter"
    ) { value ->
        Text("$value", style = MaterialTheme.typography.headlineLarge)
    }
}

AnimatedContentのトランジションをカスタマイズする

transitionSpec を使って、AnimatedContent の切り替え方法をカスタマイズできます。カウンターでは、新しい値を上へスライドさせ、古い値をスライドさせて退出させながら、フェードも組み合わせる方法がよく使われます。

using キーワードで SizeTransform を関連付けると、コンテナのサイズも滑らかに変更できます。

AnimatedContent(
    targetState = count,
    transitionSpec = {
        (slideInVertically { it } + fadeIn()) togetherWith
            (slideOutVertically { -it } + fadeOut())
    },
    label = "counter"
) { value -> Text("$value") }

リスト項目をアニメーションさせる

LazyColumn 内では、追加、削除、移動された項目を、各項目のコンテンツに Modifier.animateItem() を指定することで、所定の位置へアニメーションさせられます。

手動で状態を管理しなくても、並べ替えや挿入を滑らかに実行できます。

LazyColumn {
    items(tasks, key = { it.id }) { task ->
        Text(
            task.title,
            modifier = Modifier.animateItem()
        )
    }
}

画面全体をクロスフェードする

Crossfade は、2つの状態間をフェードさせるシンプルで目的を絞ったヘルパーです。画面全体や主要なUI状態の切り替えに適しています。

現在の状態とコンテンツラムダを渡します。状態が変わると、Crossfadeが古いコンテンツをフェードアウトし、新しいコンテンツをフェードインします。

@Composable
fun ScreenHost(screen: Screen) {
    Crossfade(targetState = screen, label = "screen") { current ->
        when (current) {
            Screen.Home -> HomeScreen()
            Screen.Profile -> ProfileScreen()
        }
    }
}

表示時の子要素を調整する

AnimatedVisibility ブロック内では AnimatedVisibilityScope を使用でき、そこから Modifier.animateEnterExit() を利用できます。これにより、個々の子要素に独自の表示・非表示アニメーションを設定し、親のトランジションに重ねて実行できます。

たとえば、パネルをスライドインさせ、その少し後にタイトルをフェードインさせることで、レイヤー感のある効果を作れます。

AnimatedVisibility(visible = show, enter = slideInVertically()) {
    Column {
        Text(
            "Title",
            modifier = Modifier.animateEnterExit(
                enter = fadeIn(tween(delayMillis = 100))
            )
        )
        Text("Body")
    }
}

確認問題

数字3から数字4への切り替えを、新しい値をフェードインおよびスライドインさせながらアニメーションさせたいとします。最適なAPIはどれですか?

まとめ:表示とトランジション

これで、コンテンツの表示、非表示、変更をアニメーションさせられるようになりました。

  • AnimatedVisibility は、fadeIn/Out、slideIn/Out、expand/shrink によって表示・非表示をアニメーションさせます。これらは + で組み合わせられます。
  • updateTransition は、1つの状態から複数の値を調整し、それぞれに独自の仕様を設定できます。
  • AnimatedContent は異なるコンテンツ間の切り替えをアニメーションさせます。Crossfade はシンプルなフェード版です。
  • Modifier.animateItem() は、リストへの挿入や並べ替えをアニメーションさせます。

次は、ジェスチャーと物理ベースのスプリングアニメーションを使って、自然でインタラクティブな動きを作ります。

よくある質問

「AnimatedVisibilityとトランジション」レッスンは無料ですか?

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

「AnimatedVisibilityとトランジション」で何を学びますか?

コンテンツの表示と非表示をアニメーションさせます。 ブラウザで直接実行するハンズオンコードでAndroid Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

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

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

「AnimatedVisibilityとトランジション」レッスンにはどのくらい時間がかかりますか?

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

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

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

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

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