Android: 拡張関数でLiveDataのSingle Eventを扱う

LiveDataは最新の値をキャッシュするため、エラー値の取扱などに困ることがあります。 適当なクラスを作るのもいいのですが、拡張関数で表現することも出来るのでその紹介です。

定義は以下のようになります。

fun <T> singleLiveData(): MutableLiveData<T> {
  // skip用の初期値を入れておく
  return MutableLiveData<T>().also { it.value = null }
}

fun <T> LiveData<T>.observeSingle(owner: LifecycleOwner, observer: ((T?) -> Unit)) {
  // 最初の値は常にskipすることで、キャッシュを無視する
  val firstIgnore = AtomicBoolean(true)
  this.observe(owner, Observer {
    if (firstIgnore.getAndSet(false)) return@Observer
    observer(it)
  })
}

使う時はこんな感じで使います。

// TestViewModel.kt
class TestViewModel: ViewModel() {
  val errorEvent = singleLiveData<String>()
}

// TestActivity.kt
testViewModel = ViewModelProviders.of(this).get(TestViewModel::class.java)
testViewModel.errorEvent.observeSingle(activity) {
  Log.d("one", it.toString())
}

メリットはサブクラスを作らずに済むところです。

参考

Written by