Изменение 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()));
}