Android ViewModel防止数据重蚀刻

Android ViewModel防止数据重蚀刻,android,firebase,android-fragments,kotlin,Android,Firebase,Android Fragments,Kotlin,我的viewModel重新蚀刻了我的数据,使得每次我到达这个片段时,我的shimmer都会继续执行,而且数据被重新蚀刻,这使得我的账单在Firebase上增加 如何防止每次我的片段弹出时再次重新蚀刻数据 在我看来 我在我的onViewCreated()中调用它,所以每次这个片段都会重新创建我的资源。加载以及fetchShops(location)都会触发,然后再次获取我的数据库,我希望每次回到这个片段时它只获取一次,知道吗 视图模型 每次调用fetchShops()时,您都在创建一个新的Live

我的viewModel重新蚀刻了我的数据,使得每次我到达这个片段时,我的shimmer都会继续执行,而且数据被重新蚀刻,这使得我的账单在Firebase上增加

如何防止每次我的片段弹出时再次重新蚀刻数据

在我看来 我在我的
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()
            }
        }
    })