Kotlin
[Kotlin] LiveData를 유연하게 사용하는 map, switchMap
Taehyung Kim, dev
2021. 1. 1. 16:10
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