type safe 방식 navigation을 적용했을 때 route명 찾기

MSU·2025년 6월 25일

Android

목록 보기
35/36

결론은 class.qualifiedName로 찾으면 된다

싱글 액티비티와 컴포즈를 사용하는 안드로이드 프로젝트에서
스캐폴드의 탑바와 바텀바를 특정 화면에서는 가려주고 특정 화면에서는 보여줘야 할 때,
아래와 같이 조건문을 사용했었다.

				val navBackStackEntry by navController.currentBackStackEntryAsState()
                val currentRoute = navBackStackEntry?.destination?.route
                
                Scaffold(
                    topBar = {
                        if (currentRoute in scaffoldShowList)
                            TopAppBar()
                    },
                    bottomBar = {
                        if (currentRoute in scaffoldShowList)
                            BottomAppBar()
                    },
                )

그리고 currentRoute를 로그에 찍어보니 아래와 같은 형식으로 나오는 것이었다!

그렇다면 조건문에 사용할 scaffoldShowList에는 저 길다란 스트링값을 전부 저장해줘야 하는건가?



현재 내가 만든 프로젝트는 컴포즈를 사용하고 type safe 방식의 네비게이션이 적용된 상태이다.

기존 컴포즈 네비게이션 라우팅 방식에서는 composable 인자로 String값을 넣었고 enum class를 만들어 활용했었다.

enum class MyRoute(val route: String){
    SplashRoute("SplashRoute"),
    LoginRoute("LoginRoute"),
    HomeRoute("HomeRoute")
}

NavHost() {
	// String값을 직접 넣거나
	composable("SplashRoute"){
    	SplashScreen()
    }
    // 또는 enum class를 사용
    composable(MyRoute.SplashRoute.route){
    	SplashScreen()
    }
}

기존 방식대로라면 SplashRoute 이 스트링 값만 scaffoldShowList에 저장해서 조건문에 사용하면 되겠지만

type safe 방식의 네비게이션에서는 아래와 같이 String이 아닌 제네릭타입으로 경로를 지정해주기 때문에..
네비게이션 라이브러리 내부적으로 해당 타입의 정규화된 이름을 경로의 고유한 ID(route 값)로 사용하게 된다.

@Serializable
object SplashRoute

@Serializable
object LoginRoute

@Serializable
object HomeRoute

    NavHost(
        navController = navController,
        startDestination = SplashRoute
    ) {
        composable<SplashRoute> { // String이 아닌 제네릭타입으로 경로를 지정해준다.
            SplashScreen(
                navigateToLogin = {
                    navController.navigate(LoginRoute) {
                        popUpTo(SplashRoute) { inclusive = true }
                    }
                },
                navigateToHome = {
                    navController.navigate(HomeRoute) {
                        popUpTo(SplashRoute) { inclusive = true }
                    }
                }
            )
        }

그래서 currentRoute를 출력해보면 해당 타입의 객체를 가리키는 고유한 주소(객체가 포함된 패키지의 경로)가 나오게 되는 것이다.

따라서 이럴때 조건문을 어떻게 비교하면 좋을까?

class.qualifiedName를 사용하면 된다.
class.qualifiedName는 패키지 이름을 포함한 클래스의 전체 이름(Full Name)을 문자열로 반환하는 코틀린의 속성이다.

그래서 아래와 같이 list에 값을 넣어주어 조건문에 활용하면 된다!

val scaffoldShowList = listOf(
    HomeRoute::class.qualifiedName
) 
profile
안드로이드공부

0개의 댓글