返回

处理ViewModel的巧妙手段:利用自定义View与ViewTreeViewModelStoreOwner

Android

在自定义视图中使用 ViewModel 的完整指南

摘要

ViewModel 是 Android 开发中至关重要的组件,它简化了 UI 数据的生命周期管理。然而,在自定义视图中使用 ViewModel 时,我们需要采用不同的方法。本文探讨了两种有效的方法,并提供了详细的说明和代码示例。

方法 1:使用 ViewTreeViewModelStoreOwner

Android 提供了 ViewTreeViewModelStoreOwner 类,它允许我们在自定义视图中使用 ViewModel。它将 ViewModel 与视图层次结构关联起来,便于获取 ViewModel 实例。

步骤:

  1. 获取与视图关联的 ViewTreeViewModelStoreOwnerViewCompat.requireViewModelStoreOwner(view)
  2. 使用 ViewModelProvider.of(viewTreeViewModelStoreOwner) 获取 ViewModel 实例

代码示例:

ViewTreeViewModelStoreOwner viewTreeViewModelStoreOwner = ViewCompat.requireViewModelStoreOwner(view);
ViewModel viewModel = ViewModelProvider.of(viewTreeViewModelStoreOwner).get(MyViewModel.class);

方法 2:实现自定义 ViewModelStoreOwner

我们还可以实现自定义的 ViewModelStoreOwner,为自定义视图提供 ViewModel 存储。

步骤:

  1. 创建一个实现 ViewModelStoreOwner 接口的类
  2. 在自定义视图中覆盖 onCreateViewModelStoreOwner(ViewModelStoreOwner parentViewModelStoreOwner) 方法,并返回自定义的 ViewModelStoreOwner 实例

代码示例:

public class MyCustomView extends View implements ViewModelStoreOwner {

    private ViewModelStore mViewModelStore;

    @Override
    protected void onCreateViewModelStoreOwner(ViewModelStoreOwner parentViewModelStoreOwner) {
        super.onCreateViewModelStoreOwner(parentViewModelStoreOwner);
        mViewModelStore = new ViewModelStore();
    }

    @Override
    public ViewModelStore getViewModelStore() {
        if (mViewModelStore == null) {
            mViewModelStore = new ViewModelStore();
        }
        return mViewModelStore;
    }
}

比较

ViewTreeViewModelStoreOwner:

  • 更简单,无需实现自定义 ViewModelStoreOwner
  • 仅适用于 Android 4.4 及以上版本

自定义 ViewModelStoreOwner:

  • 支持 Android 4.4 以下版本
  • 需要更多代码和实现工作

结论

本文提供了两种在自定义视图中使用 ViewModel 的方法。根据您的目标平台和需求,您可以选择最合适的方法。

常见问题解答

  • 为什么在自定义视图中需要 ViewModel?
    ViewModel有助于管理 UI 数据,使其独立于视图的生命周期。
  • 何时使用哪种方法?
    如果您需要支持 Android 4.4 及以上版本,则使用 ViewTreeViewModelStoreOwner 比较简单。对于较早的版本,您需要实现自定义 ViewModelStoreOwner
  • 我可以使用其他方法吗?
    本文讨论了两种最常见的方法。有其他方法,例如使用 ViewModelProviders,但它们不推荐使用。
  • ViewModel 会泄漏吗?
    只有当视图被销毁时,ViewModel 才会被清除。如果您正确实现了 ViewModelStoreOwner,则无需担心泄漏。
  • 我如何测试自定义视图中的 ViewModel?
    您可以使用 UI 测试框架,例如 Espresso,来测试 ViewModel 的行为和数据绑定。