gpt4 book ai didi

android - 使用 MVVM 架构的 ViewModel 注入(inject)(在 View 内部)

转载 作者:行者123 更新时间:2023-11-29 19:10:35 25 4
gpt4 key购买 nike

这就是我使用 MVVM (+Databinding)Dagger-2.11-rc2 创建 Adapter 的方式:

适配器:

public class ItemAdapter extends RecyclerView.Adapter<BindableViewHolder<ViewDataBinding>>{
private static int TYPE_A = 0;
private static int TYPE_B = 1;

...

@Override
public BindableViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_A) {
return new ItemViewHolder(new ItemRowView(parent.getContext()).getBinding());
}
...
}

@Override
public void onBindViewHolder(BindableViewHolder holder, int position) {
if (holder.getItemViewType() == TYPE_A) {
((ItemViewHolderBinding) holder.getBinding()).getViewModel().setItemModel(((ItemModel) getItem(position)));
}
...
}

private static class ItemViewHolder extends BindableViewHolder<ItemViewHolderBinding> {
ItemViewHolder(ItemViewHolderBinding binding) {
super(binding);
}
}
}

可绑定(bind) View 持有者:

public abstract class BindableViewHolder<ViewBinding extends ViewDataBinding> extends RecyclerView.ViewHolder {

private ViewBinding mBinding;

public BindableViewHolder(ViewBinding binding) {
super(binding.getRoot());
mBinding = binding;
}

public ViewBinding getBinding(){
return mBinding;
}
}

因为我使用的是 Dagger,所以我不会在 Adapter 中创建 ViewModels,而是在它们各自的 Android.View< 中创建(注入(inject))它们。我想这是有道理的,因为我的 Adapter 可能有 X 个 Android.View 类型,那些 View 可以有 Y 个 ViewModel,等等...

基础 View :

public abstract class BaseView<ViewBinding extends ViewDataBinding, ViewModel extends BaseViewModel> extends FrameLayout {

@Inject
ViewModel mViewModel;
protected ViewBinding mBinding;

protected abstract void initBinding(final ViewBinding binding, final ViewModel viewModel);

...

private void initView(Context context) {
ViewInjection.inject(this);

mBinding = DataBindingUtil...
initBinding(mBinding, mViewModel);
...
}
...
}

基础 View 模型:

public class BaseViewModel extends BaseObservable {...}

ItemRowView(或任何 View ):

public class ItemRowView extends BaseView<ItemRowViewBinding, ItemRowViewModel> {

@Inject
ViewModelA mViewModelA;
@Inject
ViewModelB mViewModelB;
...

@Override
protected void initBinding(ItemRowViewBinding binding, ItemRowViewModel viewModel) {
binding.setViewModel(viewModel);
binding.setViewModelA(mViewModelA);
binding.setViewModelB(mViewModelB);
...
}
}

现在,这种方法适用于 Activity 、 fragment 等,但当我使用 View 时,我必须创建一个 ViewInjecton,因为 Dagger 没有开箱即用的功能。 This is how I do it (一直读到“ViewInjection is pretty much a copy from other Injectors.”)

我的问题是(是):这是一个好方法吗?我是否正确使用了 MVVM 和 Dagger?有没有更好的方法可以在不创建 ViewInjecton (并使用 Dagger-2.11)的情况下实现这一目标?

感谢您的宝贵时间。

ps:我使用了 Adapter 示例,但如果我想使用 View 而不是 fragment ,这种方法是相同的。使用 Adapter,您只能访问 View。

最佳答案

this question 中已经有一些关于是否应该在 View 中注入(inject)的讨论。 .

Since I'm using Dagger I wont be creating the ViewModels inside the Adapter instead they will be created (injected) inside their respective Android.View. And I guess it makes sense because my Adapter may have X Android.View types, those views can have Y ViewModel, etc...

我个人觉得这有点问题,如果我在一个使用该代码的团队中工作,我更希望层与层之间有更大程度的分离。至少,

  1. 应该有一个清晰的模型层(例如从存储库或云中检索)。这些应该只是数据对象。
  2. Adapter 可以直接处理模型层,如果它很容易与“项目”层相关,即 的支持 List 的内容回收 View
  3. RecyclerView.ViewHolderViewModel 应该非常轻量,不需要注入(inject)。它本质上应该是一个属性包,可以轻松转换为 View 的某些属性(例如,setText()setColor())并且可以获取/设置。这些可以使用适配器中 onBindViewHolder 方法内的 new 关键字创建。如果这很困难,您可以提取一个工厂 (ViewModelFactory) 并将其作为适配器的依赖项注入(inject)。

简而言之,模型数据对象应该是“哑”的。对于单个 ViewHolderViewModel 也是如此。 Adapter 可以是“智能的”并且可以采用经过测试的“智能”依赖项(如必要时使用 ViewModelFactory)并且可以注入(inject)此 Adapter使用 Dagger 2 进入您的 Activity 或 Fragment。

关于android - 使用 MVVM 架构的 ViewModel 注入(inject)(在 View 内部),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45517454/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com