【Jetpack Compose/Android】Navigation Composeでアニメーションを実装する方法!

【Jetpack Compose/Android】Navigation Composeでアニメーションを実装する方法!

この記事からわかること

  • Kotlin/Android Jetpack ComposeNavigation Compose使い方
  • 画面遷移アニメーション実装方法

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

環境

Navigation Composeのアニメーション

Navigation Compose」では画面遷移時のアニメーションもある程度柔軟に設定できるようになっています。少し前まではJetpack Navigation Compose Animationという別ライブラリに切り出されていたようですが、Ver2.7.0以降から実装が安定しNavigation Composeに再度組み込まれたようです。

Navigation Compose自体の導入や使い方などは以下の記事を参考にしてください。

アニメーションの実装方法

Navigation Composeでのアニメーションはcomposableメソッドの引数で行います。以前はAnimatedNavHostに置き換える必要がありましたがNavHostのままで問題ありません。

composable(
    route = Screen.Detail.route(),
    arguments = listOf(navArgument(Screen.Detail.ARG_ITEM_ID) { type = NavType.IntType }),
    // アニメーション
    enterTransition = {
        fadeIn(animationSpec = tween(durationMillis = 500), initialAlpha = 0.5f)
    },
    // アニメーション
    exitTransition = {
        fadeOut(animationSpec = tween(durationMillis = 500), targetAlpha = 0.5f)
    },
) { backStackEntry ->
    val itemId = backStackEntry.arguments?.getInt(Screen.Detail.ARG_ITEM_ID) ?: 0
    DetailScreen(itemId = itemId, onBack = { navController.popBackStack() })
}

導入できるアニメーションタイミングは画面をpush / popした時です。

指定できるアニメーションタイミング

引数名 概要
enterTransition 画面遷移して新規画面が表示されるときのアニメーション
exitTransition 現在の画面から別の画面へ遷移するときのアニメーション
popEnterTransition 戻る操作(popBackStack)で画面が再表示されるときのアニメーション
popExitTransition 戻る操作で現在の画面が消えるときのアニメーション

アニメーションの種類

アニメーションの種類は以下の4つが用意されています。

フェード

composable(
    route = Screen.Detail.route(),
    arguments = listOf(navArgument(Screen.Detail.ARG_ITEM_ID) { type = NavType.IntType }),
    enterTransition = {
        fadeIn(animationSpec = tween(durationMillis = 500), initialAlpha = 0.5f)
    },
    exitTransition = {
        fadeOut(animationSpec = tween(durationMillis = 500), targetAlpha = 0.5f)
    },
) { backStackEntry ->
    val itemId = backStackEntry.arguments?.getInt(Screen.Detail.ARG_ITEM_ID) ?: 0
    DetailScreen(itemId = itemId, onBack = { navController.popBackStack() })
}

スライド

composable(
    route = Screen.Detail.route(),
    arguments = listOf(navArgument(Screen.Detail.ARG_ITEM_ID) { type = NavType.IntType }),
    enterTransition = {
        slideInHorizontally(
            initialOffsetX = { fullWidth -> fullWidth },
            animationSpec = tween(500)
        )
    },
    exitTransition = {
        slideOutHorizontally(
            targetOffsetX = { fullWidth -> -fullWidth / 2 },
            animationSpec = tween(500)
        )
    },
) { backStackEntry ->
    val itemId = backStackEntry.arguments?.getInt(Screen.Detail.ARG_ITEM_ID) ?: 0
    DetailScreen(itemId = itemId, onBack = { navController.popBackStack() })
}

スライドイン / アウトさせる方向はinitialOffsetY/targetOffsetXで背御することが可能です。

slideInVertically(
    // 画面の下からスライドイン
    initialOffsetY = { fullHeight -> fullHeight }, 
    // 画面の上からスライドイン
    // initialOffsetY = { fullHeight -> -fullHeight }
)
slideOutVertically(
    // 画面の下に向かってスライドアウト
    targetOffsetY = { fullHeight -> fullHeight },
    // 画面の下に向かってスライドアウト
    targetOffsetY = { fullHeight -> -fullHeight },
)

拡大・縮小(スケール)

composable(
    route = Screen.Detail.route(),
    arguments = listOf(navArgument(Screen.Detail.ARG_ITEM_ID) { type = NavType.IntType }),
    enterTransition = {
        scaleIn(
            animationSpec = tween(500),
            initialScale = 0.8f // 最初は80%のサイズから
        ) + fadeIn(animationSpec = tween(500))
    },
    exitTransition = {
        scaleOut(
            animationSpec = tween(500),
            targetScale = 0.8f // 80%に縮小しながら消える
        ) + fadeOut(animationSpec = tween(500))
    }
) { backStackEntry ->
    val itemId = backStackEntry.arguments?.getInt(Screen.Detail.ARG_ITEM_ID) ?: 0
    DetailScreen(itemId = itemId, onBack = { navController.popBackStack() })
}

FiniteAnimationSpec

各アニメーションAPIにはアニメーションの進み方を制御するために引数animationSpecFiniteAnimationSpec型で設定を渡すことが可能になっています。ここからアニメーション時間やイージングなどを制御することが可能になっています。

FiniteAnimationSpec

クラス名 概要
tween 指定した時間でイージングしながら値を変化させる
spring バネの動きをシミュレート
keyframes 特定の時刻ごとに値を設定してアニメーション
snap すぐに値を切り替える

以下のような形で指定した時間でイージングを設定することが可能です。

fadeIn(
    animationSpec = tween(
        durationMillis = 500,
        easing = LinearOutSlowInEasing
    ),
    initialAlpha = 0.5f
)

アニメーションは重ねられる

先に少し紹介しましたがアニメーションは+重ねることが可能です。

 scaleIn(
    animationSpec = tween(500),
    initialScale = 0.8f // 最初は80%のサイズから
) + fadeIn(animationSpec = tween(500))

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

Search Box

Sponsor

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index