RecyclerView.ViewHolders中的Android DataBinding具有不同的布局

hig*_*wer 5 android android-viewholder android-databinding

我正在尝试在新项目中使用androids数据绑定功能,到目前为止对此非常满意。

但是现在我在我的recyclerviews视图持有人中遇到了一个问题。

我的视图持有人使用不同的布局(基于创建时的视图类型)

public MediaViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
     switch(viewType){
          case HEADER: 
             int layout = R.layout.item_media_header;
             break;
          case DEFAULT: 
             int layout = R.layout.item_media_default;
             break;
          case SMALL: 
             int layout = R.layout.item_media_small;
             break;
     }
     View v = LayoutInflater.from(parent.getContext()).inflate(layout, parent, false);
     return new MediaViewHolder(v);
}
Run Code Online (Sandbox Code Playgroud)

因此,所有这三个布局都具有相同的视图,只是布局不同。因此,模型与视图的绑定是相同的。

无论如何,基于android创建的布局

  • ItemMediaHeaderBinding
  • ItemMediaDefaultBinding
  • ItemMediaSmallBinding

这很烂,因为这将迫使我创建3个不同的ViewHolder类或通过检查使用的布局来实例化正确的绑定类。

这种情况下有最佳实践吗?是否可以为这三个绑定类(例如“ ItemMediaBinding”)简单地创建一个超类。

提前致谢。

yen*_*rah 3

所以,我最终做的是创建一个BaseViewHolder.class,创建ViewHolder扩展这个的其他类BaseViewHolder,这样我的RecyclerView.Adapter仍然看起来很干净,因为我最终得到了这样的东西ViewHolder

public class BaseVH extends RecyclerView.ViewHolder {
    private ViewDataBinding mBinding;

    public BaseVH(ViewDataBinding mBinding) {
        super(mBinding.getRoot());
        this.mBinding = mBinding;
    }

    public void displayPost(final NewsItem post) {
        PostItemViewModel vm = new PostItemViewModel();
        vm.getPost().set(post);
        mBinding.setVariable(BR.viewModel, vm);
    }
}

public class TextPostVH extends BaseVH {
    private final PostTextBinding mBinding;

    public TextPostVH(final PostTextBinding binding) {
        super(binding);
        mBinding = binding;
    }

    //Have a method like this in the BaseVH.class
    @Override
    public void displayPost(final NewsItem post) {
        if (mBinding.getViewModel() == null) {
            mBinding.setViewModel(new PostItemViewModel());
        }
        mBinding.getViewModel().getPost().set(post);
    }
}
Run Code Online (Sandbox Code Playgroud)

所以你可以简单地调用onBindViewHolder

@Override
public void onBindViewHolder(final BaseVH holder, final int position) {
    //only a ViewHolder containing ads has to be filtered, the others work with displayPost()
    if (holder instanceof AdVH){
        holder.displayPost(mPosts.get(position));
        ((AdVH) holder).displayAd();
    } else {
        holder.displayPost(mPosts.get(position));
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以在 -tagBinding class names中指定:layoutsdata

 <data class="PostTextBinding" />
Run Code Online (Sandbox Code Playgroud)

但我不认为你可以在不同的布局中使用相同的类名。您可以在GitHub找到我的(示例)项目。

Github 上解释了另一个解决方案。他们创造了一个(真正)通用的RecyclerView.Adapter,但我发现这个......此刻对我来说有点太多了。