LiveData使用回调函数进行更改

问题描述 投票:0回答:2

所以我在存储库中有这个功能

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

这是在我的viewmodel中

var prodLive = MutableLiveData<Resource<Prod>>()
        private set
fun init(){
    prodLive = Rep.getFeaturedLive()
}
android asynchronous kotlin reactive-programming android-livedata
2个回答
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

我当然在猜测最后一行的语法,但我希望你明白这个想法。


0
投票

问题在于在这里实现了livingata。您没有发布仅设置数据的liveData值。

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

  • 由于您的api是异步的,因此您可以在api的结果之前返回livedata值。
  • api完成后,您将设置值但不发布livedata结果。
  • 设置数据后,必须调用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()));
        }
© www.soinside.com 2019 - 2024. All rights reserved.