使用回调函数更改LiveData

时间:2019-03-01 14:07:29

标签: android asynchronous kotlin reactive-programming android-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成功功能,以修改数据和状态

现在在我的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,但观察者看不到它。我应该如何修改代码,以便观察者对数据更改做出反应?我是LiveData的新手,所以如果您有其他建议,很高兴听到他们的建议

这是在我的视图模型中

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

2 个答案:

答案 0 :(得分:1)

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

我当然会在这里猜测最后一行的语法,但是希望您能理解。

答案 1 :(得分:0)

问题与livedata的实现有关。您不是仅设置数据来发布liveData值。

检查此链接:https://developer.android.com/reference/android/arch/lifecycle/LiveData#postvalue

  • 由于您的api是异步的,因此您会在api的结果之前返回livedata值。
  • API完成后,您将设置值,但不发布实时数据结果。
  • 设置数据后,您必须调用livedata.postValue(“ data”)方法。

这是我如何更新UI状态的方法。不熟悉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()));
        }