Text와 Button을 세로로 정렬하여 UI를 구성했다.
버튼을 누르면 Text값이 바뀌는 화면을 만들어 볼 것이다.
setContent {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
){
Text(
"Hello",
fontSize = 30.sp,
)
Button(onClick={
}){
Text("변경")
}
}
}
일반적인 방법
버튼을 눌렀을 때 Text의 값을 바꿔주려면 어떻게 해야 할지 생각을 해보면,
“Hello”부분을 state로 만들어줘야한다.
setContent {
val data = remember{mutableStateOf("Hello")}
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
){
Text(
data.value,
fontSize = 30.sp,
)
Button(onClick={
data.value = "world"
}){
Text("변경")
}
}
}
state선언부에 remember를 해주지 않으면, 버튼을 눌러도 값이 변경되지 않는다.
- 이유
state의 상태가 변경되면, compose가 다시 빌드가 된다 (다시 **composition**이 일어난다.) 그랬을 때, 다시 “Hello”로 초기화되었던 코드가 실행되면서 바뀌지 않는 것처럼 보이는 것이다.
따라서 **remember를 추가해서, 이전의 값을 기억**해주는 것이다.
ViewModel 사용
ViewModel은 View와 생명주기가 분리되어있다는 특성때문에, remember를 사용해주지 않아도 된다.
class MainViewModel: ViewModel(){
val data = mutableStateOf("Hello")
}
기존 안드로이드에서도 사용하던 뷰모델 사용법
⇒ 한 번 생성된 뷰모델을 계속해서 재사용할 수 있다.
class MainActivity : ComponentActivity() {
private val viewModel by viewModels<MainViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
){
Text(
viewModel.data.value,
fontSize = 30.sp,
)
Button(onClick={
viewModel.data.value = "world"
}){
Text("변경")
}
}
}
}
}
Compose에서의 ViewModel사용법
일단 gradle에 다음과 같이 추가해준다.
뷰모델을 간단하게 사용할 수 있도록 하는 라이브러리
//ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1"
compose로 setcontent에 ViewModel을 선언해주고, 동일하게 사용한다.
setContent {
val viewModel = viewModel<MainViewModel>()
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
){
Text(
viewModel.data.value,
fontSize = 30.sp,
)
Button(onClick={
viewModel.data.value = "world"
}){
Text("변경")
}
}
}
ViewModel을 사용할 때 보통 다음과 같이 데이터를 외부에서 접근할 수 있게 하지 않는다.
class MainViewModel: ViewModel(){
val data = mutableStateOf("Hello")
}
이렇게 구현하면 view쪽에서 viewmodel의 값을 바꾸는 일이 생길 수 있는데,
ex) viewmodel.data.value = "" 이런 식!
view에서 viewModel을 직접 바꾸는 일은 웬만하면 지양해야 한다. (메소드로 변경해야 함)
따라서 ViewModel을 다음과 같이 수정한다.
class MainViewModel: ViewModel(){
private val _data = mutableStateOf("Hello")
val data: State<String> = _data //읽기 전용으로 생성
}
mutable한 데이터를 private화하여 외부에서 접근할 수 없도록 하고,
State로 data를 선언하여 읽기 전용으로 만들었다.
그리고 data를 수정하기 위해 메소드를 선언해서 사용한다.
class MainViewModel: ViewModel(){
private val _data = mutableStateOf("Hello")
val data: State<String> = _data //읽기 전용으로 생성
fun changValue(){
_data.value = "World"
}
}
value값을 직접 바꿔주는 대신 changeValue함수를 사용한다.
Button(onClick={
viewModel.changValue()
}){
Text("변경")
}
테스트해보면, 회전을 했을 때도 데이터가 초기화되지 않는다.
'App > Android' 카테고리의 다른 글
[Android][Kotlin]8. JetPack Compose - State 더 알아보기 (2) | 2022.09.21 |
---|---|
[Android][Kotlin] 6. JetPack Compose - Navigation (0) | 2022.09.21 |
[Kotlin] by 키워드? (0) | 2022.09.21 |
[Android][Kotlin] 5. Jetpack Compose - Scaffold, TextField, Button, 구조분해, SnackBar, 코루틴 스코프 (0) | 2022.09.19 |
[Android][Kotlin] 4. JetPack Compose - Image, Card, State (0) | 2022.09.19 |