Mar*_*tin 5 android mvvm android-viewmodel
据我了解,当我们在片段中调用此代码时,我们将从 Activity ViewModelStore 获得一个视图模型实例:
viewModel = ViewModelProviders.of(activity!!).get(SharedViewModel::class.java)
Run Code Online (Sandbox Code Playgroud)
当fragment结束其生命周期时,该viewmodel的实例将存在于ViewModelStore中,直到activity销毁。ViewModelStore 有一个clear()方法,但它会清除其中的所有视图模型。有什么方法可以清除特定的 ViewModel 吗?
另一个解决方案是将 ViewModel 的范围限定为父片段,但是我们如何通过 ViewModelProviders.of() 初始化另一个片段中的 ViewModel?我应该将片段或视图模型实例传递给下一个片段吗?
有一种黑客方法可以清除特定ViewModel实例,您应该ViewModel使用如下所述的自定义创建实例key,并且为了清除它,您应该创建另一个实例(具有不同的ViewModel类,例如EmptyViewModel类)但具有相同的key.
ShopFragment 类:
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 ...
}
Run Code Online (Sandbox Code Playgroud)
ShopViewModel 类:
class ShopViewModel(application: Application) : AndroidViewModel(application) {
companion object {
const val KEY = "ShopViewModel"
}
// view model logic ...
}
Run Code Online (Sandbox Code Playgroud)
EmptyViewModel 这是一个虚拟 ViewModel 类:
class EmptyViewModel() : ViewModel() {
// A dummy view model!
}
Run Code Online (Sandbox Code Playgroud)
魔法发生在依赖ViewModelProvider类内部androidx.lifecycle,当您查看类get()的函数时,就会发现这里的技巧,该函数ViewModelProvider检索您以前的ViewModel实例并将其与EmptyViewModel类进行比较,并且由于它们不一样,因此它运行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;
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
如下所述,在依赖项ViewModelStore的类内部androidx.lifecycle,该put()方法将检索ShopViewModel并清除它,并替换EmptyViewModel实例。
public class ViewModelStore {
//...
final void put(String key, ViewModel viewModel) {
ViewModel oldViewModel = mMap.put(key, viewModel);
if (oldViewModel != null) {
oldViewModel.onCleared();
}
}
//...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7280 次 |
| 最近记录: |