Android ViewModel防止数据重蚀刻
我的viewModel重新蚀刻了我的数据,使得每次我到达这个片段时,我的shimmer都会继续执行,而且数据被重新蚀刻,这使得我的账单在Firebase上增加 如何防止每次我的片段弹出时再次重新蚀刻数据 在我看来 我在我的Android ViewModel防止数据重蚀刻,android,firebase,android-fragments,kotlin,Android,Firebase,Android Fragments,Kotlin,我的viewModel重新蚀刻了我的数据,使得每次我到达这个片段时,我的shimmer都会继续执行,而且数据被重新蚀刻,这使得我的账单在Firebase上增加 如何防止每次我的片段弹出时再次重新蚀刻数据 在我看来 我在我的onViewCreated()中调用它,所以每次这个片段都会重新创建我的资源。加载以及fetchShops(location)都会触发,然后再次获取我的数据库,我希望每次回到这个片段时它只获取一次,知道吗 视图模型 每次调用fetchShops()时,您都在创建一个新的Live
onViewCreated()
中调用它,所以每次这个片段都会重新创建我的资源。加载以及fetchShops(location)
都会触发,然后再次获取我的数据库,我希望每次回到这个片段时它只获取一次,知道吗
视图模型
每次调用fetchShops()
时,您都在创建一个新的LiveData
实例。这意味着任何先前创建的LiveData
(及其存储的先前值)都将丢失
相反,您应该使用位置
作为输入,按照创建liveData{}
块
每次调用fetchShops()
时,您都在创建一个新的LiveData
实例。这意味着任何先前创建的LiveData
(及其存储的先前值)都将丢失
相反,您应该使用位置
作为输入,按照创建liveData{}
块
fetchShops(location)
做了什么?@ianhanniballake更新了我的问题fetchShops(location)
做了什么?@ianhanniballake更新了我的问题所以很干净,非常感谢@ianhanniballake,最后一个问题,我们是否总是需要在switchmap中使用distinctUntilChanged()进行一次性操作?thanks@CoffeeBreak-嗯,通常只有当位置实际发生变化时才调用setLocation
distinctUntilChanged()
只是意味着您可以一次又一次地将其设置为相同的值,而无需重新加载如此干净,非常感谢@ianhanniballake,最后一个问题,我们是否总是需要将distinctUntilChanged()用于switchmap的一次性操作?thanks@CoffeeBreak-嗯,通常只有当位置实际发生变化时才调用setLocation
distinctUntilChanged()
只是意味着您可以反复将其设置为相同的值,而无需重新加载
viewModel.fetchShops(location).observe(viewLifecycleOwner, Observer {
when(it){
is Resource.Loading -> {
shimmer.visibility = View.VISIBLE
shimmer.startShimmer()}
is Resource.Success -> {
shimmer.visibility = View.GONE
shimmer.stopShimmer()
adapter.setItems(it.data)
}
is Resource.Failure -> {
Toast.makeText(requireContext(),"Error fetching data",Toast.LENGTH_SHORT).show()
}
}
})
fun fetchShops(location:String) = liveData(Dispatchers.IO) {
emit(Resource.Loading())
try{
emit(repo.fetchShops(location))
}catch (e:Exception){
emit(Resource.Failure(e))
}
}
private val locationQuery = MutableLiveData<String>
// Use distinctUntilChanged() to only requery when the location changes
val shops = locationQuery.distinctUntilChanged().switchMap { location ->
// Note we use viewModelScope.coroutineContext to properly support cancellation
liveData(viewModelScope.coroutineContext + Dispatchers.IO) {
emit(Resource.Loading())
try{
emit(repo.fetchShops(location))
}catch (e:Exception){
emit(Resource.Failure(e))
}
}
}
fun setLocation(location: String) {
locationQuery.value = location
}
// Set the current location
viewModel.setLocation(location)
// Observe the shops
viewModel.shops.observe(viewLifecycleOwner, Observer {
when(it){
is Resource.Loading -> {
shimmer.visibility = View.VISIBLE
shimmer.startShimmer()}
is Resource.Success -> {
shimmer.visibility = View.GONE
shimmer.stopShimmer()
adapter.setItems(it.data)
}
is Resource.Failure -> {
Toast.makeText(requireContext(),"Error fetching data",Toast.LENGTH_SHORT).show()
}
}
})