Запретить наблюдаемым объектам уведомлять, когда значение задано программно

#android #android-livedata

#Android #android-livedata

Вопрос:

Я хотел бы временно запретить объекту LiveData уведомлять об изменениях, не удаляя объект Observer при программном изменении значения, и вместо этого получать уведомления, когда пользователь изменяет объект live data. Есть ли способ включать / выключать уведомления для объекта LiveData, сохраняющего объект observer?

Ответ №1:

У LiveData нет такой конфигурации. Вместо этого вы можете переключить что-то внутри вашего наблюдателя, которое сообщает ему, следует ли выполнять обновление из LiveData.

Ответ №2:

Вы можете использовать пользовательский MediatorLiveData , который реализует это поведение.

Идея состоит в том, чтобы сохранить любое значение, передаваемое исходными livedata во временном поле, прежде чем устанавливать его в качестве собственного значения (и запускать наблюдателей):

 class SuppressableLiveData<T>(source: LiveData<T>) : MediatorLiveData<T>() {
    private var hasSuppressedValue = false
    private var suppressedValue: T? = null
    var isSuppressed = false
        set(value) {
            field = value
            if (!value) consumeSuppressedValue()
        }

    init {
        addSource(source) { newValue ->
            if (isSuppressed) {
                hasSuppressedValue = true
                suppressedValue = newValue
            } else {
                value = newValue
            }
        }
    }

    // even when suppressed return last update emitted from source
    override fun getValue(): T? {
        return if (hasSuppressedValue) suppressedValue else super.getValue()
    }

    // undo suppression when there are no active observers
    override fun onInactive() {
        super.onInactive()
        consumeSuppressedValue()
    }

    private fun consumeSuppressedValue() {
        if (hasSuppressedValue) {
            value = suppressedValue
            suppressedValue = null
            hasSuppressedValue = false
        }
    }
}
  

После настройки isSuppressed = true он не будет выдавать никаких обновлений из source livedata, пока не будет возвращено значение false .