据我了解,当我们在片段中调用此代码时,我们将从活动ViewModelStore中获得一个viewmodel实例:
/**
* Get a validator for an incoming registration request.
*
* @param array $data
* @return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
}
/**
* Create a new user instance after a valid registration.
*
* @param array $data
* @return \App\User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'activation_token' => [rand(1000, 9999)],
'is_active' => '0',
'is_expert' => '0',
'is_flag' => '0',
'is_subscriber' => '0',
'profile_img' => 'uploads/profile_pics/default.jpg',
]);
}
当片段将终止其生命周期时,此Viewmodel的实例将存在于ViewModelStore中,直到活动被破坏为止。 ViewModelStore有一个clear()方法,但它会清除其中的所有视图模型。有什么方法可以清除特定的ViewModel?
另一种解决方案是将ViewModel的作用域限定为父片段,但是如何通过ViewModelProviders.of()在另一个片段中初始化ViewModel?我应该将片段或viewmodel实例传递给下一个片段吗?
答案 0 :(得分:0)
有一种清除特定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 ...
}
ShopViewModel类:
class ShopViewModel(application: Application) : AndroidViewModel(application) {
companion object {
const val KEY = "ShopViewModel"
}
// view model logic ...
}
EmptyViewModel,它是一个虚拟的ViewModel类:
class EmptyViewModel() : ViewModel() {
// A dummy view model!
}
魔术在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;
}
// ...
}
如下所述,在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();
}
}
//...
}