Android/Android 더하기

Transformations LiveData 변형하기

728x90
반응형

LiveData 안의 value 값을 업데이트해주기 위해

 

Transformations는 LiveData를 위한 클래스로써, 

LiveData를 사용하면서 데이터를 가공하거나,

다른 LiveData를 만들고 싶을 때 Transformations을 사용하면 된다.

 

관련 함수로는 map()과 switchMap()이 있다.

Transformations.map

val userLiveData: MutableLiveData<User> = repository.getUser(id)

val userNameLiveData: LiveData<String> = Transformations.map(userLiveData) { user ->
    user.firstName + " " + user.lastName
}
  • map의 첫 번째 인자로 LiveData source를 넘겨준다. 넘겨준 LiveData source 가 변경될 때마다 map이 반환하는 새로운 LiveData의 value역시 새롭게 갱신된다.
  • 두 번째 인자로는 함수를 넘겨준다. 함수의 파라미터 타입은 source로 넘겨준 LiveData의 value Type(<User>)이며 함수의 return값은 무엇이든 상관없다.
  • Transformations.map의 return 값(람다의 결과물 말고)은 LiveData이다. 기존 컬렉션의 map이 그러하듯 Transformations.map 역시 내용물 요소의 값만 변환 시킬 뿐 LiveData를 리턴한다.

직관적으로 보면 userNameLiveData는 그저 userLiveData의 User 이름만 추출하여 새롭게 만든 LiveData이다. 따라서 userLiveData와 userNameLiveData는 서로 독립적인 객체인 것처럼 느껴진다. 그러나 userNameLiveData의 value는 userLiveData의 value가 바뀔 때 마다 함께 갱신된다.

어떻게 그렇게 될까? Transformations.map의 내부적으로 MediatorLiveData를 사용하고 있기 때문이다.

 

Transformations.switchMap()

 val userIdLiveData: MutableLiveData<Int> = MutableLiveData<Int>().apply { value = 1 };
 val userLiveData: LiveData<User> = Transformations.switchMap(userIdLiveData) { id ->
     repository.getUserById(id)
 }

 fun setUserId(userId: Int) {
      userIdLiveData.setValue(userId);
 }
  • switchMap의 첫 번째 인자로 LiveData source를 넘겨준다. 넘겨준 LiveData source 가 변경될 때마다 switchMap이 반환하는 새로운 LiveData의 value역시 새롭게 갱신된다.
  • 두 번째 인자로는 함수를 넘겨준다. 함수의 파라미터 타입은 source로 넘겨준 LiveData의 value Type(<Int>)이며 함수의 return값은 LiveData이어야만 한다.

map과 다른점은 람다 함수의 return값이 LiveData여야 한다는 것이다. map의 경우 람다함수의 return값이 각 요소의 값들을 변경시키는 것에 불과하며 자동으로 LiveData가 되어서 결과물이 반환되었지만, switchMap의 경우 실제로 LiveData 하나를 반환해야 한다. 그래서 switchMap은 Model단이나 Room데이터베이스와 같이 애초에 LiveData를 반환하는 기능들과 자주 함께 쓰인다.

userLiveData의 value역시 userIdLiveData의 value가 바뀌면 자동으로 갱신되는데 map과 마찬가지로 내부적으로 MediatorLiveData가 사용되기 때문이다.

 

 

 

 

 

728x90
반응형