본문 바로가기
Android (Kotlin & Compose)/Part 2. Jetpack Compose UI

[오늘의 코드 조각] [2-4] 앱의 지도를 그리다: Compose Navigation 기초

by 생각하는 개발자님 2025. 12. 23.
반응형

안녕하세요, '생각하는 개발자'입니다.

지난 시간에는 LazyColumn으로 멋진 목록을 만들어봤습니다. 하지만 목록의 아이템을 클릭해도 아무 일도 일어나지 않는다면 반쪽짜리 앱이겠죠?

제트팩 컴포즈의 내비게이션 시스템을 통해 앱의 여러 화면 사이를 이동하는 구조를 시각화한 이미지


사용자가 버튼을 눌렀을 때 다른 화면으로 이동하고, 다시 뒤로 돌아오는 기능을 구현하려면 **Navigation(내비게이션)**이라는 개념이 필요합니다. Compose에서는 이 '화면의 지도'를 어떻게 그리는지 핵심 3요소를 통해 알아보겠습니다.

1. Compose 내비게이션의 3총사

Compose에서 화면 이동을 구현하려면 딱 세 가지만 기억하면 됩니다.

  1. NavController: "운전사"입니다. 화면 이동을 명령(Maps)하고 뒤로 가기를 처리합니다.
  2. NavHost: "내비게이션이 보여줄 공간"입니다. 현재 어떤 화면을 보여줄지 결정하는 빈 컨테이너 역할을 합니다.
  3. NavGraph: "지도"입니다. 우리 앱에 어떤 화면들이 있고, 각 화면의 이름(Route)이 무엇인지 정의해둔 명단입니다.

2. 실전 예제: NavigationPractice.kt

안드로이드 스튜디오에서 두 개의 화면을 오가는 실습을 해보겠습니다. 먼저 build.gradle (Module :app) 파일에 아래 라이브러리가 추가되어 있는지 확인하세요. (없다면 추가 후 Sync Now를 눌러주세요)
Gradle
implementation("androidx.navigation:navigation-compose:2.8.0")

이제 NavigationPractice.kt 파일을 만들고 아래 코드를 작성합니다.

package com.example.composepractice.ch2_4_nav

import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController

@Composable
fun NavigationApp() {
    // 1. 운전사(NavController) 고용
    val navController = rememberNavController()

    // 2. 지도(NavHost) 작성
    NavHost(
        navController = navController,
        startDestination = "home" // 시작 화면의 이름
    ) {
        // "home"이라는 이름의 화면 정의
        composable("home") {
            HomeScreen(navController)
        }
        // "detail"이라는 이름의 화면 정의
        composable("detail") {
            DetailScreen(navController)
        }
    }
}

@Composable
fun HomeScreen(navController: NavController) {
    Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(text = "메인 화면", fontSize = 24.sp)
        Spacer(modifier = Modifier.height(16.dp))
        Button(onClick = { 
            // 3. 목적지로 이동 명령
            navController.navigate("detail") 
        }) {
            Text("상세 화면으로 가기")
        }
    }
}

@Composable
fun DetailScreen(navController: NavController) {
    Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(text = "상세 화면", fontSize = 24.sp)
        Spacer(modifier = Modifier.height(16.dp))
        Button(onClick = { 
            // 4. 뒤로 가기 명령
            navController.popBackStack() 
        }) {
            Text("뒤로 가기")
        }
    }
}

3. 핵심 정리

  • rememberNavController(): 화면 이동 상태를 관리하는 컨트롤러를 만듭니다.
  • NavHost: 앱의 모든 화면을 등록하는 허브입니다.
  • composable("경로") { ... }: 각 경로(Route)에 어떤 UI를 보여줄지 연결합니다.
  • navController.navigate("경로"): 지정한 경로로 화면을 전환합니다.

이제 여러분은 여러 개의 화면을 가진 복잡한 앱을 만들 준비가 되었습니다!

반응형