RecyclerView自己用了很长一段时间,如今基本不怎么使用ListView了,用过RecyclerView的小伙伴都知道,它的很多功能都需要自定义,比如item的点击事件,还有添加HeaderView和FooterView等等。高度的自定义使它受到众多Android码农的喜爱。网上也出现了很多封装好的RecyclerView,可以轻松的添加各种需要的事件。自己出于探索的好奇,也仔细研究了下关于HeaderView和FooterView的添加。可能说的不是很详细,如果有不对之处,还希望小伙伴们能够指出。
RecyclerView有几个非常重要的方法,分别是:getItemCount,getItemViewType,onCreateViewHolder和onBindViewHolder。
想要添加HeaderView和FooterView,就需要在getItemCount和getItemViewType上“做手脚”。
先说下如何添加FooterView,因为FooterView是添加到最底下,所以基本不影响数据List,比HeaderView简单很多。
一般getItemCount都会重写,return list.size(),所以想要添加FooterView,只需要return list.size()+1即可,然后在方法getItemViewType中,进行简单的判断
@Override
public int getItemCount() {
return items.size() + 1;
}
public static final int TYPE_FOOTER_VIEW = 1;
@Override
public int getItemViewType(int position) {
/*当position是最后一个的时候,也就是比list的数量多一个的时候,则表示FooterView*/
if (position + 1 == items.size() + 1) {
return TYPE_FOOTER_VIEW;
}
return super.getItemViewType(position);
}
细心的小伙伴会发现super.getItemViewType(position)实际上是返回一个0,也就是说,在RecyclerView中,默认是没有对ViewType进行处理的,所以真正意义上,返回什么值是有我们自己来操控的,我默认将TYPE_FOOTER_VIEW定义为1进行区别,重写了这两个方法后,只需要在onCreateViewHolder和onBindViewHolder进行简单判断,就可以产生FooterView效果了
/**一个很简单的ViewHolder,小伙伴可以根据自己的需求自定义*/
public static class FooterViewHolder extends RecyclerView.ViewHolder {
public FooterViewHolder(View itemView) {
super(itemView);
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_FOOTER_VIEW) {
/*这里返回的是FooterView*/
final View footerView = LayoutInflater.from(mContext).inflate(R.layout.adapter_foot_view, parent, false);
return new FooterViewHolder(footerView);
} else {
/*这里返回的是普通的View*/
final View view = LayoutInflater.from(mContext).inflate(R.layout.adapter_view, parent, false);
return new BaseViewHolder(view);
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder != null) {
if(holder instanceof BaseViewHolder){
/*这里返回的是普通的View*/
}else if(holder instanceof FooterViewHolder){
/*这里返回的是FooterView*/
}
}
}
说完了FooterView,再说说HeaderView,如果对FooterView已经理解了,估计应该有小伙伴知道HeaderView的实现原理了,也是一样让list的数量+1(这个是仅仅只有HeaderView,没有FooterView的情况,小伙伴不要混在一起,我只是说一下HeaderView的实现原理)
@Override
public int getItemCount() {
return items.size() + 1;
}
public static final int TYPE_HEADER_VIEW = 2;
@Override
public int getItemViewType(int position) {
/*当position是第一个的时候,则表示HeaderView*/
if (position == 0) {
return TYPE_HEADER_VIEW;
}
return super.getItemViewType(position);
}
由于HeaderView的增加,会影响到position,所以需要在onBindViewHolder中,进行调正
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder != null) {
if(holder instanceof BaseViewHolder){
/*这里返回的是普通的View*/
/*RecyclerView在增加HeaderView后,list的索引也发生了变化,需要整体-1,才是对应的list的索引*/
items.get(--position);
}else if(holder instanceof HeaderViewHolder){
/*这里返回的是HeaderView*/
}
}
}
以上就是最简单的HeaderView和FooterView的实现,只要知道了这个原理,就可以根据自己的需求,添加HeaderView和FooterView,或者同时添加。也可以根据需求,添加两个以上的HeaderView,实际上就是在getItemCount()中添加对应HeaderView的数量。
建议小伙伴们自己整理一个BaseAdapter,将HeaderView和FooterView的代码添加进去,这样以后要用到的时候,直接新建一个adapter去继承自己的BaseAdapter。