Изменение LiveData с функцией обратного вызова

Итак, у меня в репозитории есть такая функция:

fun getFeaturedLive() : MutableLiveData<Resource<Prod>> {

    val res = MutableLiveData<Resource<Prod>>()
    res.value = Resource.loading(null) //status = loading, data = null, message - null


    client.request({
        it.getOnlineProduct(param1, param2, param3)
    },{//executes on success return from server
        res.value!!.status = Status.SUCCESS
        res.value!!.data = it
    },{//executes on error return from server
        res.value!!.status = Status.ERROR
        res.value!!.message = it.message
        true //error handled
    })

    return res
}

Возвращается res, и после этого, когда приходит ответ от сервера, выполняется функция при успешном завершении, которая изменяет данные и статус.

Теперь в моем методе onViewCreated есть что-то вроде этого:

viewmodel.prodLive.observe(this, Observer {
        if (it.status == Status.ERROR) errAlert(it.message)
        if( it.status == Status.SUCCESS) initList(prodList, it.data)
        if (it.status == Status.LOADING) log("loading ...")
    })

Сервер возвращает этот продукт, вызывается функция onsuccess и данные изменяются, но наблюдатель этого не видит. Как мне изменить код, чтобы наблюдатель реагировал на изменение данных? Я новичок в LiveData, поэтому, если у вас есть другие предложения, я рад их услышать.

Это на мой взгляд модель

var prodLive = MutableLiveData<Resource<Prod>>()
        private set
fun init(){
    prodLive = Rep.getFeaturedLive()
}

person Cyber Gh    schedule 01.03.2019    source источник
comment
viewmodel.prodLive является объектом getFeaturedLive()?   -  person Stanislav Bondar    schedule 01.03.2019
comment
Да, это 'var prodLive = MutableLiveData ‹Resource ‹Prod›› () частный набор'   -  person Cyber Gh    schedule 01.03.2019
comment
Вы наблюдаете и изменяете значение в разных объектах   -  person Stanislav Bondar    schedule 01.03.2019
comment
Я присваиваю ему возвращаемое значение функции репозитория. Разве они не должны быть такими же сейчас?   -  person Cyber Gh    schedule 01.03.2019


Ответы (2)


LiveData не может определить, изменились ли внутренние элементы содержащегося в нем значения, только если вы дадите ему совершенно новое значение.

Вот чем вы сейчас занимаетесь:

res.value = Resource.loading(null) // triggers an update, new value set
res.value.status = Status.SUCCESS  // changes existing value, no update

И это то, что вам нужно сделать вместо этого, чтобы вызвать LiveData наблюдателя:

res.value = Resource.loading(null) // triggers an update, new value set
res.value = Resource.done(Status.SUCCESS, data) // triggers an update, new value set again

Я, конечно, угадываю синтаксис последней строки, но надеюсь, что вы уловили идею.

person zsmb13    schedule 01.03.2019

Проблема связана с реализацией здесь живых данных. Вы не публикуете значение liveData, только устанавливая данные.

Проверьте эту ссылку: https://developer.android.com/reference/android/arch/lifecycle/LiveData#postvalue

  • Поскольку ваш api асинхронный, вы возвращаете значение liveata перед результатом api.
  • После завершения api вы устанавливаете значение, но не публикуете результат живых данных.
  • Вы должны вызвать метод liveata.postValue ("data") после установки данных.

Вот как мне удается обновлять состояния пользовательского интерфейса. Не знаком с Kotlin, поэтому пишу на java.

private MutableLiveData<Resource<Prod>> mProductsLiveData = new MutableLiveData<>();

    public MutableLiveData<Resource<Prod>> getProductsLive() {
        return mProductsLiveData;
        }

    public void callAPI() {

        // Set Resource value to loading before calling api
        mProductsLiveData.postValue(Resource.loading(null)); 

        mRepository.getProductsFromServer(productsRequest)
        .subscribe(this::apiSuccess, this::apiError); 
        }

    public void apiSuccess(Response response) {
        // Set Resource value to Success and set data
        mProductsLiveData.postValue(Resource.success(response.getData()));
        }


    public void apiFailure(Throwable error) {
        // Set Resource value to Error and set Message
        mProductsLiveData.postValue(Resource.error(error.getMessage()));
        }
person Aman Arora    schedule 01.03.2019