Изменение 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 возвращается, и после этого, когда приходит ответ от сервера, выполняется функция on success, которая изменяет данные и статус

Теперь в моем методе 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, изменяются liveata, но наблюдатель не видит его. Как мне изменить код так, чтобы наблюдатель реагировал на изменение данных? Я новичок в LiveData, поэтому, если у вас есть какие-либо другие предложения, я рад их услышать

Это в моей точке зрения модели

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

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

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

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

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

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

Вот как мне удается обновлять состояния пользовательского интерфейса. Не знаком с Котлиным, поэтому пишу на языке 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()));
        }
Другие вопросы по тегам