如何手动清除特定的视图模型? [英] How to manually clear a specific viewmodel?
问题描述
据我了解,当我们在片段中调用此代码时,我们将从活动ViewModelStore中获得一个viewmodel实例:
As I understand when we call this code in fragments, we will have a viewmodel instance from activity ViewModelStore:
viewModel = ViewModelProviders.of(activity!!).get(SharedViewModel::class.java)
当片段将终止其生命周期时,此Viewmodel的实例将存在于ViewModelStore中,直到活动被破坏为止. ViewModelStore有一个clear()方法,但它会清除其中的所有视图模型.有什么方法可以清除特定的ViewModel?
When fragments will end their lifecycle, the instance of this viewmodel will exist in ViewModelStore until the destruction of activity. ViewModelStore has a clear() method, but it clears all viewmodels in it. Is there some way to clear specific ViewModel?
另一个解决方案是将ViewModel的作用域限定为父片段,但是如何通过ViewModelProviders.of()在另一个片段中初始化ViewModel?我应该将片段或viewmodel实例传递给下一个片段吗?
Another solution is to scope ViewModel to parent fragment, but how do we initialize ViewModel in another fragment through ViewModelProviders.of()? Should I pass fragment or viewmodel instance to the next fragment?
推荐答案
有一种清除特定ViewModel
实例的简单方法,您应在其中使用自定义的key
创建您的ViewModel
实例,如下所述,为了清除它,您应该创建另一个实例(具有不同的ViewModel
类,例如EmptyViewModel
类),但是具有相同的key
.
There is a hacky way to clear a specific ViewModel
instance in which you should create your ViewModel
instance with a customized key
as stated below, and in order to clear it you should just create another instance (with different ViewModel
class such as an EmptyViewModel
class) but with the same key
.
ShopFragment类:
ShopFragment class:
class shopFragment : BaseFragment() {
fun getViewModel() : ShopViewModel {
return ViewModelProviders.of(activity!!).get(ShopViewModel.KEY, ShopViewModel::class.java)
}
fun clearViewModel() {
ViewModelProviders.of(activity!!).get(ShopViewModel.KEY, EmptyViewModel::class.java)
}
// Fragment logic ...
}
ShopViewModel类:
ShopViewModel class:
class ShopViewModel(application: Application) : AndroidViewModel(application) {
companion object {
const val KEY = "ShopViewModel"
}
// view model logic ...
}
EmptyViewModel,它是一个虚拟的ViewModel类:
EmptyViewModel which is a dummy ViewModel class:
class EmptyViewModel() : ViewModel() {
// A dummy view model!
}
魔术发生在androidx.lifecycle
dependecy的ViewModelProvider
类内部,当您查看ViewModelProvider
类的get()
函数时,这里的技巧就揭示出来,该函数检索您以前的ViewModel
实例并进行比较它与EmptyViewModel
类一起使用,并且由于它们不相同,因此运行mViewModelStore.put(key, viewModel);
:
And the magic is happening inside ViewModelProvider
class of androidx.lifecycle
dependecy, the trick here is revealed when you take a look at the get()
function of ViewModelProvider
class which retrieves your previous ViewModel
instance and compares it with the EmptyViewModel
class and as they are not the same, it run mViewModelStore.put(key, viewModel);
:
public class ViewModelProvider {
//...
public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
ViewModel viewModel = mViewModelStore.get(key);
if (modelClass.isInstance(viewModel)) {
//noinspection unchecked
return (T) viewModel;
} else {
//noinspection StatementWithEmptyBody
if (viewModel != null) {
// TODO: log a warning.
}
}
viewModel = mFactory.create(modelClass);
mViewModelStore.put(key, viewModel);
//noinspection unchecked
return (T) viewModel;
}
// ...
}
如下所述,在androidx.lifecycle
依赖项的ViewModelStore
类中,put()
方法将检索ShopViewModel
并将其清除,并替换EmptyViewModel
实例.
As stated below inside ViewModelStore
class of the androidx.lifecycle
dependency, the put()
method will retrieve the ShopViewModel
and clear it, and replace EmptyViewModel
instance.
public class ViewModelStore {
//...
final void put(String key, ViewModel viewModel) {
ViewModel oldViewModel = mMap.put(key, viewModel);
if (oldViewModel != null) {
oldViewModel.onCleared();
}
}
//...
}
这篇关于如何手动清除特定的视图模型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!