实现的原理是重写int getItemViewType(int position),然后在onCreateViewHolder()和onBindViewHolder()方法中,根据type不同,加载不同布局。

基本实现步骤

1. 准备多套数据源

public abstract class AbsData {

    protected int type;

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }
}

public class DataInfo1 extends AbsData{

    private String tag;

    public String getTag() {
        return tag;
    }

    public void setTag(String tag) {
        this.tag = tag;
    }

}

public class DataInfo2 extends AbsData{

    private String tag;

    private int resId;

    public String getTag() {
        return tag;
    }

    public void setTag(String tag) {
        this.tag = tag;
    }

    public int getResId() {
        return resId;
    }

    public void setResId(int resId) {
        this.resId = resId;
    }
}

2. 准备多套Item布局和多套RecyclerView.ViewHolder

    class MyViewHoler01 extends RecyclerView.ViewHolder{

        TextView mainTv;

        public MyViewHoler01(View itemView) {
            super(itemView);
            mainTv = (TextView) itemView.findViewById(R.id.main_tv);
        }
    }

    class MyViewHoler02 extends RecyclerView.ViewHolder{

        TextView mainTv;
        ImageView mainIv;

        public MyViewHoler02(View itemView) {
            super(itemView);
            mainIv = (ImageView) itemView.findViewById(R.id.main_iv);
            mainTv = (TextView) itemView.findViewById(R.id.main_tv);
        }
    }

3. 重新getItemViewType()方法

    @Override
    public int getItemViewType(int position) {
        AbsData data = mDatas.get(position);
        return data.getType();
    }

4. 根据不同类型,创建不同ViewHolder并绑定不同数据

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        RecyclerView.ViewHolder vh;
        if (viewType == 1) {
            View itemView = LayoutInflater.from(mContext)
                    .inflate(R.layout.item_main_1, parent, false);
            vh = new MyViewHoler01(itemView);
        } else {
            View itemView = LayoutInflater.from(mContext)
                    .inflate(R.layout.item_main_2, parent, false);
            vh = new MyViewHoler02(itemView);
        }
        return vh;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        AbsData data = mDatas.get(position);
        if (data instanceof DataInfo1) {
            DataInfo1 dataInfo1 = (DataInfo1) mDatas.get(position);
            ((MyViewHoler01)holder).mainTv.setText(dataInfo1.getTag());
        } else if (data instanceof DataInfo2) {
            DataInfo2 dataInfo2 = (DataInfo2) mDatas.get(position);
            ((MyViewHoler02)holder).mainTv.setText(dataInfo2.getTag());
            ((MyViewHoler02)holder).mainIv.setImageResource(dataInfo2.getResId());
        }
    }

不同布局在GridLayoutManager中占不同的列

实现方法1,在调用处设置item占几列

	    mLayoutManager = new GridLayoutManager(this, 2);
        mLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                return mCustomAdapter.getItemViewType(position) == 1 ? 2 : 1;
            }
        });
        mRecyclerView.setLayoutManager(mLayoutManager);

实现方法2,在适配器中设置

    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
        if(manager instanceof GridLayoutManager) {
            final GridLayoutManager gridManager = ((GridLayoutManager) manager);
            gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    Log.d(TAG, "getSpanSize: type = " + getItemViewType(position));
                    return getItemViewType(position) == 1 ? 2 : 1;
                }
            });
        }
    }