전체 코드package com.example.modern_android_navigation_20230127
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.example.modern_android_navigation_20230127.ui.theme.Modern_Android_Navigation_20230127Theme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent{
val navController =rememberNavController()
NavHost(
navController = navController,
startDestination = "first"
){
composable("first"){
FirstScreen(navController)
}
composable("second"){
SecondScreen(navController)
}
composable("third/{value}"){backStackEntry->
ThirdScreen(
navController = navController,
value = backStackEntry.arguments?.getString("value") ?: "",
)
}
}
}
}
}
@Composable
fun FirstScreen(navController: NavController) {
val (value, setValue) =remember{
mutableStateOf("")
}
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
){
Text(text = "첫 화면")
Spacer(modifier = Modifier.height(16.dp))
Button(onClick ={
navController.navigate("second")
}){
Text(text = "두 번째!")
}
Spacer(modifier = Modifier.height(16.dp))
TextField(value = value, onValueChange = setValue)
Button(onClick ={
if (value.isNotEmpty()) {
navController.navigate("third/$value")
}
}){
Text(text = "세 번째!")
}
}
}
@Composable
fun SecondScreen(navController: NavController) {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
){
Text(text = "두 번째 화면")
Spacer(modifier = Modifier.height(16.dp))
Button(onClick ={
navController.navigateUp()
}){
Text(text = "뒤로 가기!")
}
}
}
@Composable
fun ThirdScreen(navController: NavController, value: String) {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
){
Text(text = "세 번째 화면")
Spacer(modifier = Modifier.height(16.dp))
Text(value)
Button(onClick ={
navController.navigateUp()
}){
Text(text = "두 번째!")
}
}
}
사용방법
implementation "androidx.navigation:navigation-compose:2.5.3"
Navigation을 사용하기 위해서는 Module 단위의 gradle에 위 코드를 추가해야된다.
val navController =rememberNavController()
navController
는 Navigation 구성요소의 중심 API로, 스테이트풀(Stateful)이며 앱의 화면과 각 화면 상태를 구성하는 컴포저블의 백 스택을 추적한다.
NavHost(
navController = navController,
startDestination = "first"
){
composable("first"){
FirstScreen(navController)
}
composable("second"){
SecondScreen(navController)
}
composable("third/{value}"){backStackEntry->
ThirdScreen(
navController = navController,
value = backStackEntry.arguments?.getString("value") ?: "",
)
}
}
Button(onClick ={
navController.navigate("second")
}){
Text(text = "두 번째!")
}
탐색 그래프에서 구성 가능한 대상으로 이동하려면 navigate
메서드를 사용해야 한다. navigate
는 대상의 경로를 나타내는 단일 String
매개변수를 사용한다.Button(onClick ={
navController.navigateUp()
}){
Text(text = "뒤로 가기!")
}
뒤로 가기 위해서는 navController.navigateUp()
이나 navController.popBackStack()
을 사용한다.Button(onClick ={
if (value.isNotEmpty()) {
navController.navigate("third/$value")
}
}){
Text(text = "세 번째!")
}
composable("third/{value}"){backStackEntry->
ThirdScreen(
navController = navController,
value = backStackEntry.arguments?.getString("value") ?: "",
)
}
Navigation Compose는 구성 가능한 대상 간의 인수 전달도 지원한다.
이렇게 하려면 기본 탐색 라이브러리를 사용할 때 딥 링크에 인수를 추가하는 방법과 유사한 방법으로 인수 자리표시자를 경로에 추가해야 한다.
기본적으로 모든 인수는 문자열로 파싱됩니다. composable()
의 arguments
매개변수는 [NamedNavArgument]목록을 허용합니다. navArgument메서드를 사용하여 신속하게 NamedNavArgument를 만든 다음 정확한 type을 지정할 수 있습니다.NavHost(startDestination = "profile/{userId}") {
...
composable(
"profile/{userId}",
arguments = listOf(navArgument("userId") { type = NavType.StringType })
) {...}
}
composable()
함수의 람다에서 사용할 수 있는 NavBackStackEntry에서 인수를 추출해야 합니다.composable("profile/{userId}") { backStackEntry ->
Profile(navController, backStackEntry.arguments?.getString("userId"))
}
인수를 대상에 전달하려면 navigate
호출 시 경로에 추가해야 합니다.navController.navigate("profile/user1234")
지원되는 유형 목록 : 대상 간 데이터 전달