이전 글
Android 배워보자 Compose! -(3)
이전 글 Android 배워보자 Compose! (2) 이전 글.. https://developanything.tistory.com/entry/Android-Compose-%EB%B0%B0%EC%9B%8C%EB%B3%B4%EA%B8%B0-1 Android 배워보자 Compose - (1) Compose 가 뭐지? https://developer.android.com/jetpack/compose/
developanything.tistory.com
Compose 환경에서 ViewModel 과 LiveData 사용하기
프로젝트에서 ViewModel 과 LiveData 를 이용한 MVVM 구조를 많이들 사용하셨을텐데
Compose 환경에서도 위 두 개념을 사용할 수 있습니다.(하지만 State 나 Flow 를 조금 더 지향한다고 알고있습니다.)
아래는 구글의 공식 예시 소스코드와 학습 튜토리얼입니다.(저걸 보러 가시는 것도 나쁘진 않습니다.)
Compose의 ViewModel 및 상태 | Android Developers
이 Codelab에서는 아키텍처 구성요소 중 하나인 ViewModel을 사용하는 방법을 알아봅니다. 구성 변경 중에 앱 상태를 유지하도록 ViewModel을 구현합니다.
developer.android.com
시작 전에 Module Level 의 build.gradle 에 아래와 같이 의존성을 추가해줍니다
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0")
implementation("androidx.compose.runtime:runtime-livedata:1.5.4")
ViewModel
기본적으로 ViewModel 을 사용하는 과정은 아래와 같은데
- ViewModel class 구현
- ViewModelProvider.Factory 를 상속받는 Factory class 구현
- View 에 ViewModel 을 매핑
ViewModel 은 Singleton 으로 만들어줘야 하기 때문에 2번째의 ViewModelFactory 도 같이 구현해줘야합니다.
여기서 Singleton Pattern 이란 객체의 인스턴스가 단 1개(Single) 존재하는 소프트웨어 디자인 패턴입니다.
아래는 ViewModel 클래스입니다.
class StringViewModel : ViewModel(){
private val mStringViewModel = MutableLiveData<String>()
val data : LiveData<String>
get() {
return mStringViewModel
}
init {
mStringViewModel.value = ""
}
fun setData(string: String){
mStringViewModel.value = string
}
}
Factory 클래스는 아래와 같이 구현할 수 있습니다.
class StringViewModelFactory(): ViewModelProvider.Factory{
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(StringViewModel::class.java)) {
return StringViewModel() as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
여기까진 일반적으로 ViewModel 패턴을 사용할 때와 크게 다르지 않습니다.
위에서 구현해둔 ViewModel 과 Factory 를 이용해 Composable 내부에서 이런 식으로 호출할 수 있습니다.
val stringViewModel : StringViewModel = viewModel(factory = StringViewModelFactory())
LiveData
Compose 에서는 LiveData를 observeAsState() 메서드를 이용하여 State 객체로 받아올 수 있고
이 State 객체의 getValue() 메서드를 이용하여 해당 LiveData 의 Value(값) 을 사용할 수 있습니다.
val liveData = stringViewModel.data.observeAsState()
val value: String? by liveData
위에서 구현해둔 데이터를 바탕으로 버튼을 누르면
ViewModel 에 data 를 전달하는 코드 예제를 아래와 같이 구현해보았습니다.
(누르면 랜덤 야식 추천을 해주는 예제입니다..ㅎㅎ)
val foodList: List<String> = listOf("치킨",
"피자",
"라면",
"햄버거",
"떡볶이",
"족발",
"만두",
"치즈스틱")
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ComposableTheme {
LunchMenu()
}
}
}
}
@Preview
@Composable
fun LunchMenu(){
val stringViewModel : StringViewModel = viewModel(factory = StringViewModelFactory())
val liveData = stringViewModel.data.observeAsState()
val value: String? by liveData
Box(modifier = Modifier.fillMaxSize()){
Text(
modifier = Modifier.align(Alignment.Center),
text = "오늘 야식 뭐먹지????\n\n" +
"$value",
textAlign = TextAlign.Center)
Button(onClick = {
val lunchMenu = foodList.random()
stringViewModel.setData(lunchMenu)
}, modifier = Modifier.align(Alignment.BottomCenter)
.offset(y=(-100).dp)
) {
Text(text = "돌려!")
}
}
}
위 코드의 시연 영상으로 마무리하겠습니다.
'Android > Kotlin' 카테고리의 다른 글
Android Kotlin 의 Enum class (1) | 2024.01.17 |
---|---|
Android Exoplayer 현재 재생 중인 Stream 의 Format 확인 방법 (0) | 2024.01.12 |
Android 배워보자 Compose! -(3) (3) | 2024.01.11 |
Android 배워보자 Compose! (2) (0) | 2024.01.10 |
Android 배워보자 Compose - (1) (0) | 2024.01.10 |