如何手动清除特定的视图模型?

时间:2019-03-10 21:21:33

标签: android mvvm android-viewmodel

据我了解,当我们在片段中调用此代码时,我们将从活动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实例传递给下一个片段吗?

1 个答案:

答案 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();
        }
    }
    //...
}