Kotlin Mvvm 패턴에서 Livedata로 Ui 이벤트 관리하기
안드로이드 앱 개발 중, MVVM 패턴에서 LiveData를 사용하여 UI 이벤트를 관리하기 위해서 기존에 아래와 같은 데이터 흐름 방식을 따라갔었다.
- ViewModel에서 변수 선언.
- 해당 변수를 Fragment에서 Observe.
- UI 이벤트 발생 시, ViewModel에서 해당 변수 값 변화.
- Fragment에서 Observe 했으므로 activity 실행 됨.
- 만료된 observe 해제.
이 중 5번에 대한 처리를 하지 않아, Orientation이 변경되는 등의 액션이 발생하면 계속해서 이벤트가 발생했다.
기존 코드는 아래와 같은 흐름을 따라가고 있었다.
기존 코드
ViewModel.kt
var lvStartAddAct: MutableLiveData<Boolean> = MutableLiveData(false)
...
fun openNewActivity(view: View) {
lvStartAddAct.value = true
}
Fragment.kt
mVM.lvStartAddAct.observe(viewLifecycleOwner, Observer{
// Start Activity
})
이런 방식을 따라갔기에, 화면이 재설계 될 때 마다 UI 이벤트가 반복적으로 발생하였다.
이에 아래 Event 클래스를 통해 단발적으로만 호출되도록 변경해줄 수 있다.
Event.kt
Event.kt
open class Event<out T>(private val content: T) {
var hasBeenHandled = false
private set
fun getContentIfNotHandled(): T? {
return if (hasBeenHandled) {
null
} else {
hasBeenHandled = true
content
}
}
fun peekContent(): T = content
}
EventObserer.kt
class EventObserver<T>(private val onEventUnhandledContent: (T) -> Unit) : Observer<Event<T>> {
override fun onChanged(event: Event<T>?) {
event?.getContentIfNotHandled()?.let { value ->
onEventUnhandledContent(value)
}
}
}
이 두 클래스를 생성 후, 아래처럼 코드를 변경해주면 Observe를 해제하지 않고도 단발적으로 UI 이벤트를 발생시킬 수 있다.
변경된 코드
ViewModel.kt
var lvStartAddAct = MutableLiveData<Event<Boolean>>()
fun openNewActivity(view: View) {
lvStartAddAct.value = Event(true)
}
Fragment.kt
mVM.lvStartAddAct.observe(viewLifecycleOwner, EventObserver {
// Start Activity
})
PublishSubject나 다른 방법을 통해서 UI 이벤트를 처리할 수도 있지만, 이 방법을 통해 처리를 하면 아래와 같은 장점이 있다.
- Livedata의 형태로 취급 가능.
- 상대적으로 러닝커브가 가파른 Rx를 사용하지 않고도 관리 가능.
- UI 이벤트의 특성 상 반복적으로 자주 사용될 수 밖에 없는 코드를 짧고 간결하게 사용 가능 -> 유지보수에 용이
댓글남기기