Android Navigation : 앱 내에서 화면 전환과 workflow를 관리하기 위한 시스템
Android jetpack의 Navigation Component : 앱의 navigation 구조를 정의, 구현하기 쉽도록 화면 이동, 백 스택 관리, 딥 링크 처리 등의 다양한 기능을 제공하는 도구
주요 요소
ㅇ NavHost
화면 전환이 이루어지는 컨테이너.
NavHostFragment나 NavHost Composable을 사용해 Fragment나 Compose 기반으로 설정 가능
ex)
NavHost(navController = navController, startDestination = "home") {
composable("home") { ... }
composable("details") { ... }
}
navController는 rememberNavController()를 사용해 생성된 navigation controller이다.
NavHost에서는 navigation controller와 시작 화면(startDestination)을 설정하고, 어떤 화면들이 있는지(home, details) 정의한다.
즉, 앱 실행시 처음 표시될 화면은 "home"이고,
화면의 종류는 "home"과 "details"가 있도록 한 것이다.
NavHost로 넘겨진 lambda는 궁극적으로 NavController.createGraph()를 호출해 NavGraph를 리턴한다.
createGraph()를 명시적으로 사용하려면 다음과 같이 구현할 수 있다.
val navGraph by remember(navController) {
navController.createGraph(startDestination = home)) {
composable<home> { HomeScreen( /* ... */ ) }
composable<detail> { DetailScreen( /* ... */ ) }
}
}
NavHost(navController, navGraph)
ㅇ NavGraph
화면 간의 관계와 이동 경로를 정의하는 그래프
XML파일이나 Kotlin DSL로 작성 가능
Destination(화면)끼리의 Action(이동 경로)으로 구성
ㅇ NavController
앱의 navigation을 제어하는 핵심 controller
화면 간의 이동을 프로그래밍 방식으로 처리 가능
화면 전환, 백 스택 관리, *딥 링크 처리 등 제공
Jetpack Compose를 사용하며 NavController를 생성하기 위해서는 rememberNavController()를 호출하면 된다.
* rememberNavController()는 내부적으로 remember를 사용해 NavController를 한 번만 생성, recomposition 때마다 동일한 인스턴스를 재사용한다.
composable의 최상단으로 만들어 다른 composable들을 참조할 수 있어야 한다.
* Deep Link?
앱 외부에서 특정 화면으로 바로 이동할 수 있는 기능
URI 기반으로 구현
ㅇ Destination
앱에서 이동 가능한 개별 화면(Fragment, Composable 등)
ex)
composable("home") {
HomeScreen(
onNavigateToDetails = { navController.navigate("details") }
)
}
NavHost 내부에서 위와 같이 composable을 통해 "home" 화면을 정의하는 람다 블록을 생성한다.
해당 화면의 UI를 정의하기 위해, 아래와 같이 HomeScreen 함수에 정의할 수 있다.
@Composable
fun HomeScreen(onNavigateToDetails: () -> Unit) {
Button(onClick = onNavigateToDetails) {
Text("Go to Details")
}
}
HomeScreen()은 "details" 화면으로 전환시켜주는 버튼을 가지고 있지만, navigate()를 스스로 호출하지는 않고, 버튼이 onNavigateToDetails를 호출한다.
navigation graph에 HomeScreen이 추가될 경우 onNavigateToDetails라는 매개변수(콜백)에 "navigate(route=details)"를 호출하는 lambda( = {navController.navigate("details")})를 전달한다.
실제로 사용해보기
package com.example.composetutorial
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import androidx.navigation.compose.rememberNavController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyApp {
AppNavigation() // 네비게이션 그래프 렌더링
}
}
}
}
@Composable
fun MyApp(content: @Composable () -> Unit) {
MaterialTheme { // Material3 테마 설정
content()
}
}
@Composable
fun AppNavigation() {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = "home") {
composable("home") {
HomeScreen(
onNavigateToDetails = { navController.navigate("details") }
)
}
composable("details") {
DetailsScreen()
}
}
}
@Composable
fun HomeScreen(onNavigateToDetails: () -> Unit) {
Button(onClick = onNavigateToDetails) {
Text("Go to Details")
}
}
@Composable
fun DetailsScreen() {
Text("This is the Details Screen")
}
@Preview(showBackground = true)
@Composable
fun PreviewApp() {
MyApp {
AppNavigation()
}
}
home과 details라는 두 개의 화면을 만들고, 시작 화면을 home으로 설정하였다.
home에서는 button을 누르면 details 화면으로 이동하게 되고,
details 화면에서는 "This is the Details Screen"이라는 문구만 뜨게 된다.
실행 화면
'CS > Android' 카테고리의 다른 글
Coroutine (1) (0) | 2024.12.17 |
---|---|
공통 객체 이용하기 - CompositionLocal (0) | 2024.12.17 |
Composable & Preview (0) | 2024.12.13 |
Ktlint vs Detekt vs Android Lint (1) | 2024.12.13 |
DATA BINDING (0) | 2024.12.13 |