diff --git a/core/navigation/build.gradle.kts b/core/navigation/build.gradle.kts index 3217406..9f20a59 100644 --- a/core/navigation/build.gradle.kts +++ b/core/navigation/build.gradle.kts @@ -1,6 +1,7 @@ plugins { alias(libs.plugins.twix.android.library) alias(libs.plugins.twix.android.compose) + alias(libs.plugins.twix.koin) } android { diff --git a/core/navigation/src/main/java/com/twix/navigation/AppNavHost.kt b/core/navigation/src/main/java/com/twix/navigation/AppNavHost.kt new file mode 100644 index 0000000..3544166 --- /dev/null +++ b/core/navigation/src/main/java/com/twix/navigation/AppNavHost.kt @@ -0,0 +1,60 @@ +package com.twix.navigation + +import androidx.compose.animation.core.FastOutSlowInEasing +import androidx.compose.animation.core.tween +import androidx.compose.animation.slideInHorizontally +import androidx.compose.animation.slideOutHorizontally +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.rememberNavController +import com.twix.navigation.base.NavGraphContributor +import org.koin.compose.getKoin + +@Composable +fun AppNavHost() { + val navController = rememberNavController() + val koin = getKoin() + val contributors = remember { + koin.getAll().sortedBy { it.priority } + } + val start = contributors + .firstOrNull { it.graphRoute == NavRoutes.LoginGraph } + ?.graphRoute + ?: error("해당 Graph를 찾을 수 없습니다.") + val duration = 300 + + NavHost( + navController = navController, + startDestination = start.route, + enterTransition = { + slideInHorizontally( + initialOffsetX = { fullWidth -> fullWidth }, + animationSpec = tween(duration, easing = FastOutSlowInEasing) + ) + }, + exitTransition = { + slideOutHorizontally( + targetOffsetX = { fullWidth -> -fullWidth }, + animationSpec = tween(duration, easing = FastOutSlowInEasing) + ) + }, + popEnterTransition = { + slideInHorizontally( + initialOffsetX = { fullWidth -> -fullWidth }, + animationSpec = tween(duration, easing = FastOutSlowInEasing) + ) + }, + popExitTransition = { + slideOutHorizontally( + targetOffsetX = { fullWidth -> fullWidth }, + animationSpec = tween(duration, easing = FastOutSlowInEasing) + ) + }, + modifier = Modifier.fillMaxSize() + ) { + contributors.forEach { with(it) { registerGraph(navController) } } + } +} \ No newline at end of file diff --git a/core/navigation/src/main/java/com/twix/navigation/NavRoutes.kt b/core/navigation/src/main/java/com/twix/navigation/NavRoutes.kt new file mode 100644 index 0000000..7e6c7ce --- /dev/null +++ b/core/navigation/src/main/java/com/twix/navigation/NavRoutes.kt @@ -0,0 +1,20 @@ +package com.twix.navigation + +/** + * 앱 전반에서 사용하는 Navigation Route를 여기에서 정의합니다. + * + * · 문자열 route를 직접 사용하지 않고 타입 안정성을 위해 sealed class를 활용합니다. + * · navigation argument가 필요한 경우 createRoute()를 통해 route를 생성합니다. + * · Graph의 경우 _graph로 네이밍하고 Screen의 경우에는 Composable명에서 Screen을 제외한 앞부분을 활용합니다. ex) HomeScreen -> home + * */ +sealed class NavRoutes(val route: String) { + object LoginGraph: NavRoutes("login_graph") + object Login: NavRoutes("login") + + object HomeGraph: NavRoutes("home_graph") + object Home: NavRoutes("home") + + object HomeDetail: NavRoutes("home_detail/{id}") { + fun createRoute(id: String) = "home_detail/$id" + } +} \ No newline at end of file diff --git a/core/navigation/src/main/java/com/twix/navigation/base/NavGraphContributor.kt b/core/navigation/src/main/java/com/twix/navigation/base/NavGraphContributor.kt new file mode 100644 index 0000000..87157fe --- /dev/null +++ b/core/navigation/src/main/java/com/twix/navigation/base/NavGraphContributor.kt @@ -0,0 +1,17 @@ +package com.twix.navigation.base + +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavHostController +import com.twix.navigation.NavRoutes + +/** + * priority는 우선적으로 등록해야 하는 Graph에서 값을 낮춰 사용하면 됩니다. + * ex) SplashGraph는 앱 내에서 가장 먼저 실행되어야 하는 그래프이므로 priority를 낮춰주면 됩니다. + **/ +interface NavGraphContributor { + val graphRoute: NavRoutes + val startDestination: String + val priority: Int get() = 100 + + fun NavGraphBuilder.registerGraph(navController: NavHostController) +} \ No newline at end of file