Android

[Android] LiveData 변형하기 (Transformations)

728x90

 

 

 안드로이드 미니 프로젝트를 진행하며 겪은 삽질과 거기서 배운 내용을 정리해보고자 한다. 내가 겪은 문제점은 다음과 같다.

 뷰에서 DatePicker로 날짜를 선택하면, 선택된 날짜에 해당하는 정보들을 RoomDatabase에서 찾아 리스트로 표시해준다. 날짜에 해당하는 정보들은 LiveData로 묶어서 Observer를 걸어주었고, 날짜가 선택되면 쿼리를 날려서 LiveData 안의 value 값을 업데이트해주면 되었다. 

 하지만 생각했던대로 흘러가지 않았고, LiveData 안의 value 값을 업데이트해주기 위해 이것저것 찾아본 결과 Transformations이란 것을 알게 되었다.

 

 

Transformations란?

 Transformations는 단어 뜻 그 자체로 LiveData를 변형한다고 생각하면 된다. Transformations는 LiveData를 위한 클래스로써, LiveData를 사용하면서 데이터를 가공하거나, 다른 LiveData를 만들고 싶다면 Transformations을 사용하면 된다. 관련 함수로는 map()과 switchMap()이 있다.

 

 

map()

LiveData<Y> map (LiveData<X> source, Function<X, Y> func)

 map()은 LiveData를 반환하며, 첫 번째 인자로 받는 LiveData에 이벤트가 생길 때마다 메인 스레드에서 두 번째 인자인 Function이 수행된다. 

 Function의 파라미터 타입은 source로 넘겨준 LiveData의 value 타입과 같으며, 함수의 return 값은 어떠한 값이 와도 상관없다.

val userLiveData: MutableLiveData<User> = ...

val userNameLLiveData  = Transformations.map(userLiveData) { user ->
     user.firstName + " " + user.lastName
}

 

 

switchMap()

LiveData<Y> switchMap (LiveData<X> trigger,  Function<X, LiveData<Y>> func)

 switchMap()은 map()과 거의 유사하지만, 두 번째 파라미터로 넘겨준 함수의 반환 값이 LiveData라는 차이점이 있다.

 map()과 마찬가지로 첫 번째 파라미터로 LiveData를 넘겨준다. 넘겨준 LiveData에 이벤트가 생길 때마다 Function에서 반환하는 새로운 LiveData의 value 역시 새롭게 갱신된다.

 map()의 경우 람다 함수의 return 값이 각 요소의 값들을 변경시키는 것에 불과해서 자동으로 LiveData가 반환되었지만, switchMap의 경우엔 실제로 LiveData 하나를 반환해야 한다.

 따라서 switchMap은 RoomDatabase와 같이 LiveData를 반환하는 기능들과 많이 사용한다.

val userIdLiveData: MutableLiveData<Int> = ...

val userLiveData: LiveData = Transformations.switchMap(userIdLiveData) { id ->
    repository.getUser(id)
}

fun setUserId(id: Int) {
    userIdLiveData.setValue(id)
}

 

 

출처 : https://developers-kr.googleblog.com/2019/03/viewmodel-livedata-transformations.html

728x90