[Kotlin / Compose] Navigation

Subeen·2024년 4월 29일
0

Compose

목록 보기
11/20
navController: NavHostController = rememberNavController()

navController는 Navigation을 관리하는 데 사용되는 NavHostController이다.
NavHostController는 Jetpack Compose에서 사용되며, 탐색 그래프를 관리하고 탐색 명령을 처리한다. 이를 통해 앱 내에서 화면 간의 탐색을 쉽게 관리할 수 있다.
rememberNavController() 함수는 현재 컴포넌트의 생명주기 동안 NavHostController를 보존하는 데 사용되며 NavHostController를 생성하고 기억하여 필요한 곳에서 다시 사용할 수 있도록 한다.
✨ 요약하면, navController는 Navigation을 제어하기 위해 사용되며, rememberNavController()를 통해 초기화되어 현재 컴포넌트의 생명주기 동안 유지된다.

@Composable
fun NavigationEx(
    modifier: Modifier = Modifier,
    navController: NavHostController = rememberNavController()
) {
	/*
     * NavHost는 Navigation의 호스트를 나타내며, 이 안에 각각의 화면에 해당하는 composable 함수들을 포함한다. 
     * NavHost는 navController와 함께 사용된다.
     * 현재 "Home"과 "Office"라는 두 개의 화면을 가지고 있다. 
     */
    NavHost(navController, "Home", modifier = modifier) {
        composable("Home") {
            Column {
                Text("Home")
                Button(
                    onClick = {
                        navController.navigate("Office")
                    }
                ) {
                    Text(text = "Office로 이동")
                }
            }
        }
        composable("Office") {
            Column {
                Text(text = "Office")
                Button(
                    onClick = {
                        navController.navigate("Home")
                    }
                ) {
                    Text(text = "Home 이동")
                }
            }
        }
    }
}

NavHost는 Jetpack Compose에서 사용되는 화면 간 탐색을 처리하는 데 사용되는 호스트이다.
앱 내에서 화면 전환을 담당하는 영역으로, 다양한 화면을 표시하고 사용자의 상호작용에 따라 그 사이를 탐색할 수 있도록 한다.
☝🏻 NavHost는 NavHostController와 함께 사용되어야 하며, NavHostController는 NavHost에 대한 탐색을 제어하는 역할을 한다.

navController.navigate() 함수는 NavHostController를 통해 화면 간 탐색을 수행하는 메서드이다.
이 함수를 호출하면 NavHostController는 지정된 목적지로 화면을 변경하고 해당 목적지에 대한 적절한 UI를 표시한다.
Ex) navController.navigate("Home") : Home이라는 목적지로 이동하라는 명령을 NavHostController에 전달한다. NavHostController는 이 명령을 처리하고, 해당 목적지에 대한 화면을 표시한다.

popUpTo

popUpTo는 목적지로 이동할 때 현재 스택에 있는 다른 목적지들을 모두 제거하는 데 사용된다.
이를 통해 사용자가 이전에 방문한 여러 화면을 스택에서 제거하고, 목적지로의 새로운 경로를 설정할 수 있다.

@Composable
fun NavigationEx(
    modifier: Modifier = Modifier,
    navController: NavHostController = rememberNavController()
) {
    NavHost(navController, "Home", modifier = modifier) {
        composable("Home") {
            Column {
                Text("Home")
                Button(
                    onClick = {
                        navController.navigate("Office") {
                            popUpTo("Home")
                        }
                    }
                ) {
                    Text(text = "Office로 이동")
                }
                Button(
                    onClick = {
                        navController.navigate("Playground") {
                            popUpTo("Home")
                        }
                    }
                ) {
                    Text(text = "Playground 이동")
                }
            }
        }
        composable("Office") {
            Column {
                Text(text = "Office")
                Button(
                    onClick = {
                        navController.navigate("Home") {
                            popUpTo("Home")
                        }
                    }
                ) {
                    Text(text = "Home 이동")
                }
                Button(
                    onClick = {
                        navController.navigate("Playground") {
                            popUpTo("Home")
                        }
                    }
                ) {
                    Text(text = "Playground 이동")
                }
            }
        }
		...
    }
}
navController.navigate("Office") {
    popUpTo("Home")
}

Office로 이동하면서, 현재 스택에 있는 모든 목적지를 제거하고 Home 목적지만 남기는 명령으로 Home 화면 이외의 다른 화면을 건너뛰고 Office 화면으로 이동할 수 있다.

inclusive

popUpTo("Home") { inclusive = true }

popUpTo 함수의 옵션 중 하나로, 해당 목적지를 포함하여 이전의 모든 목적지를 제거하는 데 사용된다.
해당 코드의 경우, Home 이전의 모든 목적지들을 스택에서 제거하고, Home 목적지도 함께 제거한다.

@Composable
fun NavigationEx(
    modifier: Modifier = Modifier,
    navController: NavHostController = rememberNavController()
) {
    NavHost(navController, "Home", modifier = modifier) {
        composable("Home") {
            Column {
                Text("Home")
                Button(
                    onClick = {
                        navController.navigate("Office") {
                            popUpTo("Home") {
                                /*
                                Home -> Office -> Playground 순으로 이동할 때
                                Home에서 Office로 이동할 때 처음의 Home을 없애서 Office가 된다.
                                Office에서 Playground로 이동할 때는 스택에 Office 밖에 없으므로 popUpTo는 동작하지 않고 바로 Playground로 이동한다.

                                inclusive 예시
                                Home -> Login -> Mail
                                popUpTo("Login") { inclusive = true }
                                이동하는 순간에 Login을 찾아 같이 제거함으로써 스택에는 Home, Mail만 남아있다.
                                메일을 확인한 후에 백버튼을 누르면 Home으로 탈출이 가능하다.
                                 */
                                inclusive = true
                            }
                        }
                    }
                ) {
                    Text(text = "Office로 이동")
                }
                Button(
                    onClick = {
                        navController.navigate("Playground") {
                            popUpTo("Home") {
                                inclusive = true
                            }
                        }
                    }
                ) {
                    Text(text = "Playground 이동")
                }
            }
        }
        ...

launchSingleTop

navController.navigate("Home") { launchSingleTop = true }

navigate() 함수의 옵션 중 하나로, 목적지로 이동할 때 해당 목적지가 이미 스택의 맨 위에 있으면 새로운 인스턴스를 생성하지 않고, 기존의 인스턴스를 재사용하여 새로운 목적지로 이동하는 데 사용된다.
해당 코드의 경우, Home 목적지로 이동할 때, 스택의 맨 위에 있는 목적지가 이미 Home인 경우에는 새로운 인스턴스를 생성하지 않고, 기존의 Home 인스턴스를 재사용하여 화면을 업데이트한다.

@Composable
fun NavigationEx(
    modifier: Modifier = Modifier,
    navController: NavHostController = rememberNavController()
) {
    NavHost(navController, "Home", modifier = modifier) {
        composable("Home") {
            Column {
                Text("Home")
                Button(
                    onClick = {
                        navController.navigate("Office") {
                            popUpTo("Home") {
                                inclusive = true
                            }
                        }
                    }
                ) {
                    Text(text = "Office로 이동")
                }
                Button(
                    onClick = {
                        navController.navigate("Playground") {
                            popUpTo("Home") {
                                inclusive = true
                            }
                        }
                    }
                ) {
                    Text(text = "Playground 이동")
                }
                Button(
                    onClick = {
                        navController.navigate("Home") {
                            launchSingleTop = true
                        }
                    }
                ) {
                    Text(text = "Home 이동")
                }
            }
        }
        ...

동적으로 생성 된 경로에 대한 화면 정의

@Composable
fun NavigationEx(
    modifier: Modifier = Modifier,
    navController: NavHostController = rememberNavController()
) {
    NavHost(navController, "Home", modifier = modifier) {
        composable("Home") {
            Column {
                Text("Home")
                Button(
                    onClick = {
                        navController.navigate("Office") {
                            popUpTo("Home") {
                                inclusive = true
                            }
                        }
                    }
                ) {
                    Text(text = "Office로 이동")
                }
                Button(
                    onClick = {
                        navController.navigate("Playground") {
                            popUpTo("Home") {
                                inclusive = true
                            }
                        }
                    }
                ) {
                    Text(text = "Playground 이동")
                }
                Button(
                    onClick = {
                        navController.navigate("Argument/test") {
                            launchSingleTop = true
                        }
                    }
                ) {
                    Text(text = "test 아이디로 연결")
                }
            }
        }
        
        ... 
        
        /*
         * 동적으로 생성된 경로에 대한 화면을 정의한다. 
         * "Argument/{userId}"는 경로 패턴을 나타낸다.
         * {userId}는 동적인 부분으로, 사용자 ID와 같은 값을 나타낸다. 
         * { backStackEntry -> ... } 람다 함수는 해당 경로에 대한 라우팅 정보를 받아와서 화면을 구성한다. 
         * val userId = backStackEntry.arguments?.getString("userId") 는 백스택엔트리에서 "userId"라는 키를 가진 인수를 가져와서 "userId" 변수에 할당한다. 
         * Text(text = "userId: $userId")는 가져온 userId 값을 사용하여 화면에 표시하는 텍스트를 생성한다.
         */
        composable("Argument/{userId}") { backStackEntry ->
            val userId = backStackEntry.arguments?.getString("userId")
            Text(text = "userId: $userId")
        }
    }
}
profile
개발 공부 기록 🌱

0개의 댓글