탐색 3

Navigation 3은 Jetpack Compose를 위해 처음부터 설계된 탐색 라이브러리입니다. 이 가이드에서는 Wear OS 애플리케이션에서 Navigation 3을 구현하는 방법을 설명합니다.

핵심 개념

  • NavKey: 앱의 대상(화면)을 위한 유형 안전 직렬화 가능 식별자입니다.
  • NavBackStack: 탐색 기록을 나타내는 NavKey 인스턴스의 변경 가능한 목록입니다. 이 목록에서 직접 항목을 푸시하고 팝합니다.
  • rememberNavBackStack: 구성 변경 및 프로세스 종료 전반에서 백 스택을 만들고 유지하는 컴포저블입니다.
  • NavDisplay: 백 스택을 관찰하고 활성 화면을 렌더링하는 핵심 UI 구성요소입니다.
  • EntryProvider: NavKey를 실제 @Composable UI에 연결하는 매핑 DSL입니다.
  • SwipeDismissableSceneStrategy: 화면을 스와이프하여 닫기 동작으로 래핑하고 기본 제공 뒤로 애니메이션을 처리하는 Wear 전용 전략입니다.

1단계: 종속 항목 추가

필요한 Navigation 3, Wear Compose, 직렬화 종속 항목을 프로젝트에 추가합니다.

Groovy

dependencies {
    // Core Navigation 3 APIs
    implementation "androidx.navigation3:navigation3-runtime:1.2.0-alpha02"
    implementation "androidx.navigation3:navigation3-ui:1.2.0-alpha02"

    // Wear OS specific Navigation 3 integration
    implementation "androidx.wear.compose:compose-navigation3:1.6.1"

    // Kotlinx Serialization for type-safe routing
    implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.10.0"
}

Kotlin

dependencies {
    // Core Navigation 3 APIs
    implementation("androidx.navigation3:navigation3-runtime:1.2.0-alpha02")
    implementation("androidx.navigation3:navigation3-ui:1.2.0-alpha02")

    // Wear OS specific Navigation 3 integration
    implementation("androidx.wear.compose:compose-navigation3:1.6.1")

    // Kotlinx Serialization for type-safe routing
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.10.0")
}

2단계: 대상 정의 (NavKey)

화면은 인터페이스를 구현하는 강력한 유형의 직렬화 가능한 객체 또는 데이터 클래스로 정의됩니다.NavKey

@Serializable
sealed interface Screen : NavKey {
    @Serializable
    data object Home : Screen

    @Serializable
    data class Details(val itemId: String) : Screen
}

3단계: NavDisplay 및 백 스택 설정

애플리케이션의 루트에서 백 스택과 Wear OS 장면 전략을 초기화한 다음 NavDisplay에 연결합니다.

// 1. Create the persistent back stack starting at the Home screen
val backStack = rememberNavBackStack(Screen.Home)

// 2. Initialize the Wear OS swipe-to-dismiss strategy
val strategy = rememberSwipeDismissableSceneStrategy<NavKey>()

// 3. Render the NavDisplay
NavDisplay(
    backStack = backStack,
    sceneStrategies = listOf(strategy),
    entryProvider = entryProvider {
        // 4. Map keys to Composables
        entry<Screen.Home> {
            HomeScreen(
                onNavigateToDetails = { id -> backStack.add(Screen.Details(id)) }
            )
        }
        entry<Screen.Details> { key ->
            DetailsScreen(
                itemId = key.itemId,
                onBack = { backStack.removeAt(backStack.lastIndex) }
            )
        }
    }
)

4단계: 탐색 작업 실행

백 스택은 맞춤설정된 MutableList이므로 탐색이 매우 간단합니다. backStack 인스턴스에서 직접 작업을 실행합니다.

  • 앞으로 이동: backStack.add(Screen.Details("123"))
  • 뒤로 이동: backStack.removeLast() 또는 backStack.removeLastOrNull()
  • 지우기 및 재설정: backStack.clear(); backStack.add(Screen.Home) (또는 목록 작업을 사용하여 스택을 대체합니다).

5단계: (선택사항) 대상을 ViewModel 범위 지정

기본적으로 ViewModelActivity로 범위가 지정됩니다. Navigation 3 은 백 스택의 NavEntryViewModel을 안전하게 범위 지정하는 특정 아티팩트 (lifecycle-viewmodel-navigation3)를 제공합니다. 대상이 백 스택에서 사라지면 ViewModel이 삭제됩니다.

  1. 종속 항목을 추가합니다.

    implementation("androidx.lifecycle:lifecycle-viewmodel-navigation3:...")
    
  2. NavDisplayentryDecorators에 ViewModel 스토어 데코레이터를 추가합니다. Compose rememberSaveable 상태를 유지하기 위해 맞춤 데코레이터를 제공할 때 SaveableStateHolderNavEntryDecorator도 명시적으로 포함해야 합니다.

    NavDisplay(
        backStack = backStack,
        sceneStrategies = listOf(strategy),
        entryDecorators = listOf(
            rememberSaveableStateHolderNavEntryDecorator(),
            rememberViewModelStoreNavEntryDecorator()
        ),
        entryProvider = entryProvider {
            entry<Screen.Home> {
                // Any viewModel() requested here will be scoped to this NavEntry
                val viewModel: HomeViewModel = viewModel()
            }
        }
    )