场景
嗨,我有一个带有ViewPager的活动。在ViewPagerAdapter中,我使用不同的数据创建同一片段的实例。在每一个实例中,我都初始化一个ViewModel
val dataViewModelFactory = this.activity?.let { DataViewModelFactory(it) }
mainViewModel = ViewModelProviders.of(this, dataViewModelFactory).get(MainViewModel::class.java)
在我的片段中,当我调用API 时,我观察到两个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获取数据。
问题
代码在我的片段中多次到达observe块。当我从一个片段返回到前一个片段时,即使没有调用API,也会执行观察块上的代码。
我尝试了什么
我尝试在ViewModel初始化中使用一个活动实例
mainViewModel = ViewModelProviders.of(activity,dataViewModelFactory).get(MainViewModel::class.java)
但这并没有奏效。
请帮忙,
如果您想阻止观察器的多次调用,您只需将MutableLiveData
更改为SingleLiveEvent
即可。读取此
它可能会对您有所帮助:
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)
首先,当您想在LiveData
上发布值时,使用toOneTimeEvent()
扩展函数将其封装在OneTimeEvent
:中
liveData.postValue(yourObject.toOneTimeEvent())
第二,当你在LiveData
上观察时,对传递的值使用consume { }
函数来获得OneTimeEvent
的特性。您将确信consume { }
的块将只执行一次。
viewModel.liveData.observe(this, Observer {
it.consume { yourObject ->
// TODO: do whatever with 'yourObject'
}
})
在这种情况下,当片段恢复时,您的代码块不会再次执行。