본문 바로가기
Kotlin

[Kotlin] LiveData를 유연하게 사용하는 map, switchMap

by Taehyung Kim, dev 2021. 1. 1.
728x90

map

inline fun <X, Y> LiveData<X>.map(crossinline transform: (X) -> Y): LiveData<Y> =
        Transformations.map(this) { transform(it) }

내부에서 Transformations.map을 사용한다. Transformations.map 함수는 아래와 같습니다.

    @MainThread
    @NonNull
    public static <X, Y> LiveData<Y> map(
            @NonNull LiveData<X> source,
            @NonNull final Function<X, Y> mapFunction) {
        final MediatorLiveData<Y> result = new MediatorLiveData<>();
        result.addSource(source, new Observer<X>() {
            @Override
            public void onChanged(@Nullable X x) {
                result.setValue(mapFunction.apply(x));
            }
        });
        return result;
    }

map 함수의 기능을 요약하면 아래와 같습니다.

  • source로 입력된 LiveData 객체의 값을 Observing한다.
  • 값이 바뀔 때마다 result 값이 변화한다.
  • 변화된 값을 return.

switchMap

inline fun <X, Y> LiveData<X>.switchMap(
    crossinline transform: (X) -> LiveData<Y>
): LiveData<Y> = Transformations.switchMap(this) { transform(it) }

map과 마찬가지로 Transformations 클래스의 switchMap을 사용합니다.

    @MainThread
    @NonNull
    public static <X, Y> LiveData<Y> switchMap(
            @NonNull LiveData<X> source,
            @NonNull final Function<X, LiveData<Y>> switchMapFunction) {
        final MediatorLiveData<Y> result = new MediatorLiveData<>();
        result.addSource(source, new Observer<X>() {
            LiveData<Y> mSource;

            @Override
            public void onChanged(@Nullable X x) {
                LiveData<Y> newLiveData = switchMapFunction.apply(x);
                if (mSource == newLiveData) {
                    return;
                }
                if (mSource != null) {
                    result.removeSource(mSource);
                }
                mSource = newLiveData;
                if (mSource != null) {
                    result.addSource(mSource, new Observer<Y>() {
                        @Override
                        public void onChanged(@Nullable Y y) {
                            result.setValue(y);
                        }
                    });
                }
            }
        });
        return result;
    }

switchMap 함수의 기능 또한 map 기능과 유사합니다만 return 값에 차이점이 있습니다.

  • source로 입력된 LiveData 객체의 값을 Observing한다.
  • 값이 바뀔 때마다 result 값이 변화한다.
  • LiveData 타입을 return.

 

사용 방법

map

private val count: MutableLiveData<Int> = MutableLiveData()

val apple: LiveData<Int> = count.map { it }

fun setAppleCount(num: Int) {
	count.value = num
}

 

switchMap

private val count: MutableLiveData<Int> = MutableLiveData()

val apple: LiveData<Int> = count.switchMap {
        getAppleCount(it)
}

fun setAppleCount(num: Int) {
	count.value = num
}

private fun getAppleCount(count: Int): LiveData<Int> {
    val liveData = MutableLiveData<Int>()
    liveData.run {
        value = count
    }
    return liveData
}
728x90

댓글