0.前言
上一篇学了如何对adapter进行基本的自定义:
https://blog.csdn.net/user11223344abc/article/details/81708502
这篇我们来看看如何为adapter多封装一个添加header的方法.
1.代码
ViewHolder
package android.zj.com.rcvheaderdemo;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* ViewHolder
*/
public class ViewHolder extends RecyclerView.ViewHolder {
private SparseArray<View> mViews;
private View mConvertView;
/**
* 0.VuewHolder构造函数
* @param context
* @param itemview
* @param parent
*/
public ViewHolder(Context context, View itemview, ViewGroup parent) {
super(itemview);
mConvertView = itemview;
mViews = new SparseArray<View>();
}
/**
* 1.渲染条目,并创建viewholder,这个方法一般在onCreateViewHolder内进行调用
* @param context
* @param parent
* @param layoutid
* @return
*/
public static ViewHolder getHolderById(Context context, ViewGroup parent, int layoutid) {
View itemview = LayoutInflater.from(context).inflate(layoutid, parent, false);
ViewHolder holder = new ViewHolder(context, itemview, parent);
return holder;
}
public static ViewHolder getHolderByView(Context context, ViewGroup parent, View view) {
ViewHolder holder = new ViewHolder(context, view, parent);
return holder;
}
/**
* 2.扩展方法,根据ViewId获取View
* @param viewid
* @param <T>
* @return
*/
public <T extends View> T getView(int viewid) {
View view = mViews.get(viewid);
if (view == null) {
view = mConvertView.findViewById(viewid);
mViews.put(viewid, view);
}
return (T) view;
}
}
Adapter
package android.zj.com.rcvheaderdemo;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import java.util.ArrayList;
import java.util.List;
public abstract class MyAdapter<T> extends RecyclerView.Adapter<ViewHolder> {
private Context mContext;
private int mLayoutid;
private List<T> mDatas;
private AdapterView.OnItemClickListener monItemClickListener = null;
private int ITEM_TYPE_HEADER = 1;
private int ITEM_TYPE_NORMAL = 0;
/**
* headerview容器
*/
private List<View> mHeaderViews = new ArrayList<>();
/**
* 添加header
* @param header
*/
public void addHeaderView(View header){
mHeaderViews.add(header);
notifyDataSetChanged();
}
/**
* adapter构造函数
* @param mContext
* @param mLayoutid
* @param mDatas
*/
public MyAdapter(Context mContext, int mLayoutid, List<T> mDatas) {
this.mContext = mContext;
this.mLayoutid = mLayoutid;
this.mDatas = mDatas;
}
@Override
public int getItemViewType(int position)
{
if(position < mHeaderViews.size()){
return ITEM_TYPE_HEADER;
}
return ITEM_TYPE_NORMAL;
}
/**
* onCreateViewHolder --> inflate操作 根据 ItemViewType 渲染不同的布局
**/
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ViewHolder viewHolder = null;
if (viewType == ITEM_TYPE_HEADER) {
viewHolder = ViewHolder.getHolderByView(mContext, parent, mHeaderViews.get(mHeaderViews.size()-1));
} else {
viewHolder = ViewHolder.getHolderById(mContext, parent, mLayoutid);
}
return viewHolder;
}
/**
* 暴露出来的接口
* @param holder
* @param position
*/
public abstract void convert(ViewHolder holder, T position);
/**
* 摆放
* @param holder
* @param position
*/
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
if(position < mHeaderViews.size()){
return;
}
convert(holder, mDatas.get(position));
}
/**
* 获取高度
*
* @return
*/
@Override
public int getItemCount() {
if (mDatas == null) {
return 0;
}
return mDatas.size();
}
}
2.重点分析
判断是否是header或者footer的条件
这个是根据角标来判断的。
@Override
public int getItemViewType(int position)
{
if(position < mHeaderViews.size()){
return ITEM_TYPE_HEADER;
}
return ITEM_TYPE_NORMAL;
}
onCreateViewHolder根据不同的条件进行不同的渲染,其中就包含header
/**
* onCreateViewHolder --> inflate操作 根据 ItemViewType 渲染不同的布局
**/
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ViewHolder viewHolder = null;
if (viewType == ITEM_TYPE_HEADER) {
viewHolder = ViewHolder.getHolderByView(mContext, parent, mHeaderViews.get(mHeaderViews.size()-1));
} else {
viewHolder = ViewHolder.getHolderById(mContext, parent, mLayoutid);
}
return viewHolder;
}
onBindViewHolder根据不同的条件进行不同的布局处理,监测到是header,则不必做过多处理
/**
* 摆放
* @param holder
* @param position
*/
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
if(position < mHeaderViews.size()){
return;
}
convert(holder, mDatas.get(position));
}
Demo
https://github.com/zj614android/recyclerHeaderAdapter
3.Thanks
基本方法1:https://blog.csdn.net/qibin0506/article/details/49716795
基本方法2:https://blog.csdn.net/qq_38228254/article/details/78374348
添加header方法:https://blog.csdn.net/qibin0506/article/details/49716795
rc设计思想:https://www.jianshu.com/p/9ddfdffee5d3
SparseArray与SparseArrayCompat区别:https://blog.csdn.net/androidiscoding/article/details/79201682