视图模型发射多次,而不仅仅是一次



我试图在这个片段中只发出一次,它在我第一次进入这个片段时发出,但是如果我导航到下一个片段并返回,它会再次发出,我不想要它,因为它会重新获取我的数据,相反,如果我回到这个片段,我想避免重新获取。

片段

private val viewModel by viewModels<LandingViewModel> {
VMLandingFactory(
LandingRepoImpl(
LandingDataSource()
)
)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val sharedPref = requireContext().getSharedPreferences("LOCATION", Context.MODE_PRIVATE)
val nombre = sharedPref.getString("name", null)
location = name!!
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupRecyclerView()
fetchShops(location)
}
private fun fetchShops(localidad: String) {
viewModel.setLocation(location.toLowerCase(Locale.ROOT).trim())
viewModel.fetchShopList
.observe(viewLifecycleOwner, Observer {
when (it) {
is Resource.Loading -> {
showProgress()
}
is Resource.Success -> {
hideProgress()
myAdapter.setItems(it.data)
}
is Resource.Failure -> {
hideProgress()
Toast.makeText(
requireContext(),
"There was an error loading the shops.",
Toast.LENGTH_SHORT
).show()
}
}
})
}

视图模型

private val locationQuery = MutableLiveData<String>()
fun setLocation(location: String) {
locationQuery.value = location
}
val fetchShopList = locationQuery.distinctUntilChanged().switchMap { location ->
liveData(viewModelScope.coroutineContext + Dispatchers.IO) {
emit(Resource.Loading())
try{
emit(repo.getShopList(location))
}catch (e:Exception){
emit(Resource.Failure(e))
}
}
}

在这里,当我转到下一个片段并返回时,位置不会改变。有什么想法可以解决这个问题吗?我正在使用导航组件。

这就是LiveData的工作方式,它会在恢复时始终为您提供最新信息。我建议使用 kotlin 的Flow因为它可以满足您的需求,在您完成发射后,您不会再获得更新

尝试使用 SingleLiveEvent 它应该只发出一次

我昨天看到了你的问题,试图研究我回答为什么distinctUntilChanged((不适合你但没有成功 - 老实说,我从来没有使用过不久前添加的"扩展"。

在任何情况下,快速修复都是添加一个已经加载的变量,如下所示:

private val locationQuery = MutableLiveData<String>()
private var alreadyLoaded = false
fun setLocation(location: String) {
if (!alreadyLoaded) {
alreadyLoaded = true
locationQuery.value = location
}
}
val fetchShopList = locationQuery.distinctUntilChanged().switchMap { location ->
liveData(viewModelScope.coroutineContext + Dispatchers.IO) {
emit(Resource.Loading())
try{
emit(repo.getShopList(location))
}catch (e:Exception){
emit(Resource.Failure(e))
}
}
}

视图模型不会发出多次。您的活动将被重新创建,因此您可以多次观察。(当您旋转屏幕等时也会发生这种情况(

这位先生有一个关于这种情况的非常好和清晰的博客

最新更新