Compose에서는 데이터의 상태가 변경되었을 때, setContent가 다시 호출된다. 이를 Recomposition이라고 하는데, 따로 데이터를 저장해 두지 않는다면, Recomposition 되었을 때 데이터가 초기화 되어버린다.
Compose 에서는, 명령형 기반 뷰와는 달리, 데이터가 변경되면 상태를 명시적으로 알려줘야 한다.
ex) TextField에서 onValueChange를 정의해줘야 입력한 문자가 뷰에 표시된다.
본 포스팅에서는, Compose에서 데이터 변경이 발생하여 Recomposition 되었을 때, 데이터를 유지시키기 위한 방법으로 어떤 것이 있는지 알아보려고 한다.
setContent{
val data =remember{mutableStateOf("Hello")}
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
){
Text(text = data.value,
fontSize = 30.sp)
Button(onClick ={
data.value = "world"
}){
Text("변경")
}
}
}
MutableStateOf은, Observable한 MutableState를 생성하고, 런타임 시 Compose에 통합되는 Observable 유형이다.
💡 interface MutableState<T> : State<T> {
override var value: T
}
Composable은 Observable하기 때문에,
value를 관찰하고 있다가 value가 변경되면 이를 감지하고 Recomposition이 예약된다.
MutableState를 remember라는 composable을 이용하여 변수를 선언하게 되면 initial composition에서 메모리에 저장되어 Recomposition 때 값을 반환받아 사용할 수 있다. 또한 값이 변경되어 ReComposition 할 때 마다 값을 저장할 수도 있다.
하지만, 화면이 회전되는 경우 Activity가 재 시작하기 때문에, 다시 그려지게 되면 remember로도 값이 유지되지 않는다. 이 때는 rememberSaveable을 사용하면 된다.
💡 ViewModel이란 ? AAC(Android Architecture Components) 중 하나로 UI 관련 데이터를 저장하고 관리해 주는 역할을 한다.
class MainActivity : ComponentActivity() {
private val viewModel byviewModels<MainViewModel>()
...
setContent {
Column(
...
){
Text(text = viewModel.data.value,
fontSize = 30.sp)
Button(onClick = {
viewModel.data.value = "world"
}) {
Text("변경")
}
}
}
class MainViewModel : ViewModel(){
private val data = mutableStateOf("Hello")
}
이번에는 Compose에서 제공하는 ViewModel을 사용한다. setContent 내에서 사용할 수 있다.
위의 2번에서 ViewModel을 사용해 데이터 유지를 할 수 있었으나, ViewModel의 멤버 변수를 조작한다는 문제가 발생한다.
따라서, 본 데이터를 private 으로 선언하고 Compose에서 추적할 수 있는 State형의 데이터를 하나 생성하여, Getter 처럼 사용할 수 있게 한다.
또한, changeValue 라는 메서드를 만들어서 View에서는 값이 바뀌는 내부 동작에 대해서는 몰라야 하는 관심사 분리를 만족한다.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent{
val viewModel =viewModel<MainViewModel>()
Column(
...
){
Text(text = viewModel.data.value,
fontSize = 30.sp)
Button(onClick ={
viewModel.changeValue()
}){
Text("변경")
}
}
}
}
class MainViewModel : ViewModel(){
private val _data =mutableStateOf("Hello")
val data : State<String> = _data
fun changeValue(){
_data.value = "world"
}
}
[출처] https://growup-lee.tistory.com/entry/Android-Compose-State-관리
https://www.charlezz.com/?p=45464
제 머릿속에 데이터를 저장해두지 않아서 항상 데이터 초기화가 되는걸가요?ㅠ