📌
Jetpack Compose入門 アプリを作る知識-3(画面遷移アニメーション~navigation-animation)
概要
Jetpack Composeで画面遷移の際にアニメーションをしたい場合にどうやるかという話です。
残念ながら、2022/03/28の段階では、いまだに安定版がリリースされていなくて、試験運用版APIとして提供されています。
なので、正式版の場合は実装方法が全然変わっている可能性があります。
実装方法
前回の実装の画面遷移をアニメーションさせようと思います。
ライブラリを追加します。
+ implementation "com.google.accompanist:accompanist-navigation-animation:0.24.5-alpha"
Kotlinの実装は、画面遷移の実装が分かっていれば、非常に簡単です。(単純な画面遷移は以前の記事を参照ください)
アニメーション無しの実装とほぼ変わりません。
変更箇所は、以下の箇所だけです。
-
rememberNavController
->rememberAnimatedNavController
-
NavHost
->AnimatedNavHost
-
import androidx.navigation.compose.composable
->import com.google.accompanist.navigation.animation.composable
・・・
-import androidx.navigation.compose.composable
+import com.google.accompanist.navigation.animation.composable
・・・
- val navController = rememberNavController()
- NavHost(navController = navController, startDestination = "main") {
+ val navController = rememberAnimatedNavController()
+ AnimatedNavHost(navController = navController, startDestination = "main") {
また、試験運用版APIなので、
@ExperimentalAnimationApi
or @OptIn(ExperimentalAnimationApi::class)
を利用している関数に記述する必要があります。
@OptIn(ExperimentalAnimationApi::class)
@Composable
fun MyContentView() {
結果、こんなフェードイン、フェードアウトなアニメーションになります。(このgifは再生時間スケールをx10に設定しています)
これは、AnimatedNavHost()
関数を見るとわかりますが、enterTransition
とexitTransition
でfadeInを指定しているからです。
@Composable
@ExperimentalAnimationApi
public fun AnimatedNavHost(
navController: NavHostController,
startDestination: String,
modifier: Modifier = Modifier,
contentAlignment: Alignment = Alignment.Center,
route: String? = null,
enterTransition: (AnimatedContentScope<NavBackStackEntry>.() -> EnterTransition) =
{ fadeIn(animationSpec = tween(700)) },
exitTransition: (AnimatedContentScope<NavBackStackEntry>.() -> ExitTransition) =
{ fadeOut(animationSpec = tween(700)) },
popEnterTransition: (AnimatedContentScope<NavBackStackEntry>.() -> EnterTransition) = enterTransition,
popExitTransition: (AnimatedContentScope<NavBackStackEntry>.() -> ExitTransition) = exitTransition,
builder: NavGraphBuilder.() -> Unit
)
なので、この引数を変えれば色々とアニメーションを変更できます。
たとえば、iOS風に横スライド遷移も可能です。
val navController = rememberAnimatedNavController()
AnimatedNavHost(navController = navController, startDestination = "main",
enterTransition = {
slideIn { fullSize -> IntOffset(fullSize.width, 0) }
},
popEnterTransition = {
slideIn { fullSize -> IntOffset(-fullSize.width, 0) }
},
exitTransition = {
slideOut { fullSize -> IntOffset(-fullSize.width, 0) }
},
popExitTransition = {
slideOut { fullSize -> IntOffset(fullSize.width, 0) }
},
) {
composable("main") {
ListTitles(contents = mocks) { index ->
navController.navigate("second/$index")
}
}
composable(
"second/{index}",
arguments = listOf(navArgument("index") { type = NavType.IntType })
) { backStackEntry ->
Detail(backStackEntry.arguments?.getInt("index") ?: 1) {
navController.navigateUp()
}
}
}
ソーシャル経済メディア NewsPicks メンバーの発信を集約しています。公式テックブログはこちら→ tech.uzabase.com/archive/category/NewsPicks
Discussion