본문 바로가기
Android Jetpack Compose/Navigation, Route

공유되는 Route 의 Navigation 구현방법 # Jetpack Compose

by Developer88 2023. 4. 22.
반응형

Jetpack Compose의 Navigation을 사용할 때,

페이지가 교차되는 Route 가 존재하는 경우가 생기게 되는데요.

오늘은 이런 교차되는 혹은 공유되는 Route 의 구현 방법에 대해서 정리해 보도록 하겠습니다.

다만, 이 글은 Jetpack Compose 의 Navigation의 기본 구현방법에 대해서는 다루지 않습니다.

 

1. 큰 그림

다음과 같은 형태의 NavigationGraph 가 있다고 가정해 보겠습니다.

Main페이지에는 Home과 Profile 이 존재하는데,

둘다 같은 Settings로 routing 되어야 합니다.

 

Home -> Settings
Profile -> Settings

 

 

이럴 때는 어떻게 구성해야 할까요?

Home route 에 Settings route를 넣고, Profile 라우트에도 Settings route 를 넣어주어야 할까요?

이럴 때는 Shared Route 를 별도로 정의해해서 사용하는 것이 좋은데요.

아래에서 보도록 하겠습니다.

 

2. 교차되는 Navigation (공유되는 Navigation)

MainRoutes는 아래와 같이 만들어 주고요.

이어서 같이 sharedRoutes 라고 하는 교차되는 라우트가 있다고 가정해 보겠습니다.

 

enum class MainRoutes(val route: String) {
    Home("home"),
    Profile("profile")
}

 

이이서 아래와 같이 교차되는 Route 에 대해서도 Route를 만들어 줍니다.

 

enum class SharedRoutes(val route: String) {
    Settings("settings")
}

 

2. SharedSettingsGraph

nestedNavigation을 다룰 때처럼,

NavGraphBuilder의 확장함수로, sharedSettingsGraph()함수를 만들어 줍니다.

참고로 뒤의 Settings는 임의로 만들어 준 이름입니다.

이것은 확장함수로 반드시 아래와 같은 이름을 사용할 필요가 없습니다.

 

fun NavGraphBuilder.sharedSettingsGraph(navController: NavController) {
    SettingsScreen(
        onNavigate = { navController.navigate(it.route) },
        onNavigateBackToHome = {
            navController.popBackStack(MainRoutes.Home.route, inclusive = false)
            navController.navigate(MainRoutes.Home.route)
        }
    )
}

 

 

onNavigateBackToHome 은 특정버튼을 누를 경우,

route들이 stack에 쌓이지 않고, backStack에서 꺼내서 뒤로 돌아가기 위함입니다.

계속 UI를 유지할 필요도 없고, 굳이 Stack에 쌓아놀 필요가 없는 경우도 있습니다.

 

3. 각각의 페이지에서 Navigate 하기

이제 각 페이지의 UI를 Composable 함수로 그려줍니다.

단순하게 텍스트와 버튼만 넣기로 하겠습니다.

 

@Composable
fun HomeScreen(onNavigate: (SharedRoutes) -> Unit) {
    Column {
        Text("Hello Home")
        Button(onClick = { onNavigate(SharedRoutes.Settings) }) {
            Text("Settings 로 이동하기")
        }
    }
}

@Composable
fun ProfileScreen(onNavigate: (SharedRoutes) -> Unit) {
    Column {
        Text("Profile")
        Button(onClick = { onNavigate(SharedRoutes.Settings) }) {
            Text("Settings 로 이동하기")
        }
    }
}

@Composable
fun SettingsScreen(onNavigate: (MainRoutes) -> Unit, onNavigateBackToHome: () -> Unit) {
    Column {
        Text("Settings")
        Button(onClick = { onNavigate(MainRoutes.Home) }) {
            Text("Home 으로 이동")
        }
        Button(onClick = { onNavigate(MainRoutes.Profile) }) {
            Text("Profile 로 이동")
        }
        Button(onClick = onNavigateBackToHome) {
            Text("뒤로 돌아가기")
        }
    }
}

 

 

이제 마지막으로 NavHost 에 위의 Route 들을 담아주기만 하면 됩니다.

교차되는 Navigation이 정상적으로 동작하기 위해서는,

NavHost안에 위에서 확장함수로 정의했던,

sharedSettingsGraph(navController)를 넣어주어야 합니다.

 

@Composable
fun MainNavigation() {
    val navController = rememberNavController()
    NavHost(navController, startDestination = MainRoutes.Home.route) {
        composable(MainRoutes.Home.route) {
            HomeScreen(onNavigate = { navController.navigate(it.route) })
        }
        composable(MainRoutes.Profile.route) {
            ProfileScreen(onNavigate = { navController.navigate(it.route) })
        }
        sharedSettingsGraph(navController)
    }
}

 

이제 교차되는 Route가 정상적으로 구현되는 것을 볼 수 있습니다.

728x90

댓글