Изменение LiveData с помощью функции обратного вызова - PullRequest
0 голосов
/ 01 марта 2019

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

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

Это в моей модели просмотра

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

Ответы [ 2 ]

0 голосов
/ 01 марта 2019

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

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

  • Поскольку ваш 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()));
        }
0 голосов
/ 01 марта 2019

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

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

...