Navigation
1. dependency 추가 필요
// Navigation
implementation("androidx.navigation:navigation-compose:2.4.0-alpha10")
2. naviController
값을 넘기고자 할 때, composable("third/{value}") 처럼,
naviBackStackEntry 객체. 이 객체를 부르면, {value} 로 넘어온 것을 받을 수 있음.
navController.navigateUp() : 뒤로 가기
3. Sample Code
@OptIn(ExperimentalComposeUiApi::class)
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)
}
// 값을 전달하기 위해서 {value} 로 묶어서 사용함.
composable("third/{value}") { backStackEntry ->
ThirdScreen(
navController = navController,
value = backStackEntry.arguments?.getString("value") ?: "",
)
}
}
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@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 ("두번째! ")
}
Spacer(modifier = Modifier.height(16.dp))
TextField(value = value, onValueChange = setValue)
Button(onClick = {
if (value.isNotEmpty()) {
navController.navigate("third/$value")
}
}) {
Text ("세번째! ")
}
}
}
@Composable
fun SecondScreen(naviController: NavController) {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(text = "두 번째 화면")
Spacer(modifier = Modifier.height(16.dp))
Button(onClick = {
naviController.navigateUp()
}) {
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 ("뒤로 가기 ")
}
}
}
ViewModel
상태 변경 시, 컴포즈가 변경되는 컴포지션이 일어나는데, 이때 컴포즈를 다시 그린다. 때문에 remember 키워드를 사용하지 않으면 계속해서 처음 선언한 값으로 초기화가 이뤄지기 때문에, 변경하고자 하는 state로 변경 시킬 수 없다. 기존에 있던 데이터를 기억하기 위해서 `remember`키워드를 사용한다.
val data = remember { mutableStateOf("Hello") }
ViewModel 사용 시,
뷰모델 액티비티와 라이플사이클을 같이 가져감
컴포즈 안에서 viewModel 사용해보기
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2")
추가하면 컴포즈 안에서 viewModel 에서 불러올 수 있다.
setContent {
val viewModel = viewModel<MainViewModel>()
Sample Code
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val viewModel = viewModel<MainViewModel>()
// val data = remember { mutableStateOf("Hello") }
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
viewModel.data.value,
fontSize = 30.sp
)
Button(onClick = {
viewModel.changeValue()
// viewModel.data.value = "World"
}) {
Text("변경")
}
}
}
}
}
class MainViewModel : ViewModel() {
// viewmodel 의 경우, 액티비티와 라이프사이클을 공통으로 관리함.
// 외부에서 접근되지 않도록 막고, state 타입으로 공개하도록 함.
private val _data = mutableStateOf("Hello")
val data: State<String> = _data
// 메서드를 제공해서 외부에서 value 변할 수 있게 설정 시킬 수 있음
fun changeValue() {
_data.value = "World"
}
}
'[ Jetpack Compose ]' 카테고리의 다른 글
News Application Clone #2 (0) | 2023.11.14 |
---|---|
News Application Clone #1 (0) | 2023.11.08 |
Jetpack Compose Basic #4 (0) | 2023.11.07 |
Jetpack Compose Basic #2 (0) | 2023.10.30 |
Jetpack Compose Basic #1 (0) | 2023.10.30 |