android - 在 RecyclerView 适配器中实现多个 ViewHolder 类型

标签 android android-layout android-recyclerview android-view android-viewholder

这可能是讨论而不是问题。

实现多种类型的正常方式

如您所知,如果我们要在RecyclerView中实现多种类型,我们应该提供多个扩展RecyclerView.ViewHolderCustomViewHolder

例如,

class TextViewHolder extends RecyclerView.ViewHolder{
    TextView textView;
}

class ImageViewHolder extends RecyclerView.ViewHolder{
    ImageView imageView;
}

然后我们必须重写getItemViewType,并在onCreateViewHolder中构造TextViewHolderImageViewHolder

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    if (viewType == 0) {
        return new ImageViewHolder(mLayoutInflater.inflate(R.layout.item_image, parent, false));
    } else {
        return new TextViewHolder(mLayoutInflater.inflate(R.layout.item_text, parent, false));
    }
} 

上面的代码是正常的,但还有另一种方式。

另一种方式

我认为只有一个 CustomViewHolder 就足够了。

 class MultipleViewHolder extends RecyclerView.ViewHolder{
    TextView textView;
    ImageView imageView;

    MultipleViewHolder(View itemView, int type){
       if(type == 0){
         textView = (TextView)itemView.findViewById(xx);
       }else{
         imageView = (ImageView)itemView.findViewById(xx);
       }
    }
 }

您在开发工作中使用哪种方式?

最佳答案

我个人喜欢 Yigit Boyar 建议的方法在 this talk (快进到 31:07)。不是从 getItemViewType() 返回一个 constant int,而是直接返回布局 id,它也是一个 int 并且保证是唯一的:


    @Override
    public int getItemViewType(int position) {
        switch (position) {
            case 0:
                return R.layout.first;
            case 1:
                return R.layout.second;
            default:
                return R.layout.third;
        }
    }

这将允许您在 onCreateViewHolder() 中执行以下操作:


    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View view = inflater.inflate(viewType, parent, false);

        MyViewHolder holder = null;
        switch (viewType) {
            case R.layout.first:
                holder = new FirstViewHolder(view);
                break;
            case R.layout.second:
                holder = new SecondViewHolder(view);
                break;
            case R.layout.third:
                holder = new ThirdViewHolder(view);
                break;
        }
        return holder;
    }

其中 MyViewHolder 是一个抽象类:


    public static abstract class MyViewHolder extends RecyclerView.ViewHolder {

        public MyViewHolder(View itemView) {
            super(itemView);

            // perform action specific to all viewholders, e.g.
            // ButterKnife.bind(this, itemView);
        }

        abstract void bind(Item item);
    }

FirstViewHolder 如下:


    public static class FirstViewHolder extends MyViewHolder {

        @BindView
        TextView title;

        public FirstViewHolder(View itemView) {
            super(itemView);
        }

        @Override
        void bind(Item item) {
            title.setText(item.getTitle());
        }
    }

这将使 onBindViewHolder() 成为单行代码:


    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        holder.bind(dataList.get(holder.getAdapterPosition()));
    }

因此,您会将每个 ViewHolder 分开,其中 bind(Item) 将负责执行特定于该 ViewHolder 的操作.

关于android - 在 RecyclerView 适配器中实现多个 ViewHolder 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46390768/

相关文章:

android - 如何在我的 Android 应用程序中获取 BroadcastReceiver for Action :android. intent.action.MAIN 和 android.intent.category.HOME

java - 在 RealmRecyclerViewAdapter 上调用 updateData 实际上并不是更新数据

xml onClicks 不再适用于 android lollipop 中的 Activity

Android fragment 和适配器

android - 如何在顶部第一个项目装饰后剪辑 recyclerView

android - 为 android gridview 注册上下文菜单

安卓布局。使用 <include> 使表格布局的列大小相等

android - Android 操作项上的通知徽章

Android数据绑定(bind)layout_width : You must supply a layout_width attribut

android recyclerview 不一致检测到无效的 recycler viewholder 位置