将值设置为 MutableLiveData 时执行自定义逻辑的最佳方式

Best way to execute custom logic when setting value to MutableLiveData

当设置 MutableLiveData 的值时,最推荐的执行自定义逻辑的方法是什么?

我有一个 ViewModel 有几个属性 isConnectingisConnected。 当 isConected 更改

时,我想将 isConnecting 设置为 false
class MyViewModel : ViewModel() {
    private var _isConnecting = MutableLiveData<Boolean>()
    val isConnecting: LiveData<Boolean>
        get () = _isConnecting
    
    private var _isConnected = MutableLiveData<Boolean>()
    val isConnected: LiveData<Boolean>
        get () = _isConnected
}

一种方法是在 MyViewModel 中创建一个函数并设置两个属性:

fun setConnected(value: Boolean) {
    _isConnected.value = value
    _isConnecting.value = false
}

这没关系,但千万不要手动设置 _isConnected 并始终使用函数 setConnected()。无法保证,因此可能存在错误。

另一种方法是让 MyViewModel 观察它自己的 MutableLiveData:

class MyViewModel : ViewModel() {

    // ...

    private val isConnectedObserver = Observer<Boolean> {
        _isConnecting.value = false
    }

    init {
        isConnected.observeForever(isConnectedObserver)
    }

    override fun onCleared() {
        super.onCleared()
        isConnected.removeObserver(isConnectedObserver)
    }
}

这避免了第一种方法的问题,但是太糟糕了。

但是有没有更好的办法呢?例如以某种方式使用设置器?

使用 MediatorLiveData 观察其他 LiveData 对象并对来自它们的 onChanged 事件做出反应:

class MyViewModel : ViewModel() {

    private var _isConnecting = MediatorLiveData<Boolean>().also { liveData ->
        liveData.addSource(_isConnected) { connected ->
            // isConnected changed, some logic here
            if (connected) {
                liveData.value = false
            }
        }
    }
    val isConnecting: LiveData<Boolean>
        get() = _isConnecting

    private var _isConnected = MutableLiveData<Boolean>()
    val isConnected: LiveData<Boolean>
        get() = _isConnected
}