Android ViewModel MutableLiveData 多次更新

Android ViewModel MutableLiveData update multiple times

场景

你好, 我有一个带有 ViewPager 的 Activity。在 ViewPagerAdapter 中,我创建了具有不同数据的同一片段的实例。 在每个实例中,我都会初始化一个 ViewModel

val dataViewModelFactory = this.activity?.let { DataViewModelFactory(it) }
mainViewModel = ViewModelProviders.of(this, dataViewModelFactory).get(MainViewModel::class.java)

在我的片段中,我在调用 APIs

时观察到两个 MutableLiveData
mainViewModel.isResponseSuccessful.observe(this, Observer { it ->

        if(it) {
            //do Something
        }else{
            Toast.makeText(activity, "Error in Sending Request", Toast.LENGTH_SHORT).show()
        }


    })

    mainViewModel.isLoading.observe(this, Observer {
        if (it) {
            println("show progress")
        } else {
            println("dismiss progress")
        }
    })

在每个片段中,单击按钮我加载另一个片段。如果需要,调用 API 来获取数据。

问题

代码在我的片段中多次出现在观察块中。当我从一个片段返回到前一个片段时,即使没有调用 API,也会执行观察块上的代码。

我试过的

我尝试在 ViewModel 初始化中使用 activity 实例

mainViewModel = ViewModelProviders.of(activity,dataViewModelFactory).get(MainViewModel::class.java)

但是没有用。

请帮忙,

如果你想防止多次调用你的观察者,你可以将 MutableLiveData 更改为 SingleLiveEvent。阅读 this

可能对您有帮助:

import java.util.concurrent.atomic.AtomicBoolean

class OneTimeEvent<T>(
    private val value: T
) {

    private val isConsumed = AtomicBoolean(false)

    private fun getValue(): T? =
        if (isConsumed.compareAndSet(false, true)) value
        else null

    fun consume(block: (T) -> Unit): T? =
        getValue()?.also(block)
}

fun <T> T.toOneTimeEvent() =
    OneTimeEvent(this)

首先,当您想 post LiveData 上的值时,使用 toOneTimeEvent() 扩展函数将其包装在 OneTimeEvent:

liveData.postValue(yourObject.toOneTimeEvent())

其次,当你在LiveData上观察时,对传递的值使用consume { }函数来获得OneTimeEvent的特征。您将确定 consume { } 的块将只执行一次。

viewModel.liveData.observe(this, Observer {
            it.consume { yourObject ->
                // TODO: do whatever with 'yourObject'
            }
        })

在这种情况下,当片段恢复时,您的代码块不会再次执行。