1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Jetpack Composeでナビゲーションアニメーションの作成

Last updated at Posted at 2023-11-22

Compose を使用したナビゲーション:

Navigation は、アプリ内のあるデスティネーションから別のデスティネーションにナビゲートできるようにする Jetpack ライブラリです。Navigation ライブラリには、Jetpack Compose による一貫性のある自然なナビゲーションを可能にする具体的なアーティファクトも用意されています。

設定:

Compose をサポートするには、アプリ モジュールの build.gradle ファイルで次の依存関係を使用します。

build.gradle.kts
dependencies {

  //https://developer.android.com/jetpack/androidx/releases/navigation
    implementation("androidx.navigation:navigation-compose:2.7.5")
}

画面デスティネーション:

ScreenDestinations.kt ナビゲーショングラフを作成する。
https://gist.github.com/ihridoydas/331ab66955e84b826ea168c790360639

ScreenDestinations.kt
sealed class ScreenDestinations(val route: String) {
     object HomeScreen : ScreenDestinations("home_screen")
     object ViewScreen : ScreenDestinations("view_screen")
}

ナビグラフビルダー:

NavGraphBuilder.kt グラフの構築に使用されるビルダー
https://gist.github.com/ihridoydas/31e6e459a39b0f29ffb275a921c6eab1

NavGraphBuilder.kt
@ExperimentalAnimationApi
fun NavGraphBuilder.screen(
    route: String,
    arguments: List<NamedNavArgument> = listOf(),
    content: @Composable AnimatedVisibilityScope.(NavBackStackEntry) -> Unit
) {
    val animSpec: FiniteAnimationSpec<IntOffset> = tween(500, easing = FastOutSlowInEasing)

    composable(
        route,
        arguments = arguments,
        enterTransition = {
            slideInHorizontally(
                initialOffsetX = { screenWidth -> screenWidth },
                animationSpec = animSpec
            )
        },
        popEnterTransition = {
            slideInHorizontally(
                initialOffsetX = { screenWidth -> -screenWidth },
                animationSpec = animSpec
            )
        },
        exitTransition = {
            slideOutHorizontally(
                targetOffsetX = { screenWidth -> -screenWidth },
                animationSpec = animSpec
            )
        },
        popExitTransition = {
            slideOutHorizontally(
                targetOffsetX = { screenWidth -> screenWidth },
                animationSpec = animSpec
            )
        },
        content = content
    )
}

ナビホスト: (ネストグラフを NavHost に追加する)

NavHost.kt グラフの構築に使用されるビルダー
https://gist.github.com/ihridoydas/5df933e1a6ebbbce44dd321d7bf62067
デスティネーションをネストグラフにグループ化して、アプリの UI 内の特定のフローをモジュール化できます。その例として、自己完結型のログインフローがあります。

ネストグラフはデスティネーションをカプセル化します。ルートグラフと同様、ネストグラフには、ルートによって開始デスティネーションとして識別されるデスティネーションが必要です。これは、ネストグラフに関連付けられたルートに移動するときに誘導されるデスティネーションです。

NavHost.kt
@OptIn(ExperimentalAnimationApi::class)
@Composable
fun MainAnimationNavHost(
    navController: NavHostController,
    startDestination: String = ScreenDestinations.HomeScreen.route,
) {
    NavHost(
        navController = navController,
        startDestination = startDestination,
    ) {
        screen(ScreenDestinations.HomeScreen.route) {
            HomeScreen(navController = navController)
        }
        screen(ScreenDestinations.ViewScreen.route) {
            ViewScreen(
                navController = navController,
                onBackPress = {
                //navigateTo のためNavHostControllerを作成します。
                    navController.navigateTo(ScreenDestinations.HomeScreen.route)
                })
        }


    }
    //Back Handler
    BackHandler {
        navController.popBackStack()
    }

}

ナビホストコントローラー:

NavHostController.kt
https://gist.github.com/ihridoydas/1b5c45c3684b46a032650d368567f776

NavHostController.kt
fun NavHostController.navigateTo(route: String) = navigate(route) {
    popUpTo(route)
    launchSingleTop = true
}

それで、必要なナビゲーションコンポーネントを作成終わりました、これから画面を作成します。

ホーム画面:

HomeScreen.kt

HomeScreen.kt
@Composable
fun HomeScreen(
    navController: NavController,
) {
    Box(modifier = Modifier.fillMaxSize()) {
        Column(
            modifier = Modifier.fillMaxSize(),
            Arrangement.Center,
            Alignment.CenterHorizontally
        ) {
            Button(
                modifier = Modifier
                    .size(300.dp, 60.dp),
                onClick = {
                    navController?.navigate(ScreenDestinations.ViewScreen.route) {
                        popUpTo(ScreenDestinations.HomeScreen.route) {
                            inclusive = false
                        }
                    }
                }) {
                Text(text = "ビュー画面へナビゲーション")
            }
        }

    }

}

ビュー画面:

ViewScreen.kt

ViewScreen.kt
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ViewScreen(
    navController: NavController,
    onBackPress :()-> Unit,
) {
    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text(text = "ナビゲーション") },
                navigationIcon = {
                    IconButton(
                        onClick = {
                            onBackPress()
                        },
                        modifier = Modifier
                    ) {
                        Icon(Icons.Filled.ArrowBack, contentDescription = "Back")
                    }
                }
            )
        },
        content = {
            Box (modifier = Modifier.padding(it)){
                Column (modifier = Modifier
                    .fillMaxSize()){
                }
            }

        }
    )

}

結果:

Jetpack Composeでナビゲーションアニメーションを作成できました。

ファイル名
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?