前言:我们在使用RecyclerView的过程中其实还是有很多问题的,前面提到的没有默认的分割线,很是让人蛋疼啊,但现在有出了个问题,不能添加头部和底部,这一度让我认为这货还是没有最爱的ListView好用啊,哈哈,既然谷歌出来了,我们就要使用,没有头和脚那我们就给他造出头和脚,可以仿照ListView那样优雅的实现。
先给大家推荐一下鸿祥大神是如何封装RecyclerView的头部和底部的吧,传送带开启:http://blog.csdn.net/lmj623565791/article/details/51854533
翔神封装的过于强大,对于我这样的小白来说只能是以后学习的对象,大家不妨看一下我的
分析:如果想自己动手也封装一个头部和尾部,那只有参考ListView是如何封装的,大家看一下ListView的关键代码,是不是就明白了很多
ListView.addHeaderView(){
if (mAdapter != null) {
if (!(mAdapter instanceof HeaderViewListAdapter)) {
mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, mAdapter);
}
};
ListView.setAdapter(){
if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {
mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);
} else {
mAdapter = adapter;
}
}
所以我们也要封装一个类似于HeaderViewListAdapter这样的Adapter(具体细节看代码注释):
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.Adapter;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
/**
* Created by Fly on 2017/5/15.
*/
public class WrapRecyclerViewAdapter extends RecyclerView.Adapter {
private Adapter mAdapter;
private ArrayList<View> mHeaderViewInfos;
private ArrayList<View> mFooterViewInfos;
public WrapRecyclerViewAdapter(ArrayList<View> headerViewInfos, ArrayList<View> footerViewInfos, Adapter adapter) {
mAdapter = adapter;
if (headerViewInfos == null) {
mHeaderViewInfos = new ArrayList<View>();
} else {
mHeaderViewInfos = headerViewInfos;
}
if (footerViewInfos == null) {
mFooterViewInfos = new ArrayList<View>();
} else {
mFooterViewInfos = footerViewInfos;
}
}
@Override
public int getItemCount() {
if (mAdapter != null) {
return getFootersCount() + getHeadersCount() + mAdapter.getItemCount();
} else {
return getFootersCount() + getHeadersCount();
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
//也要划分三个区域
int numHeaders = getHeadersCount();
if (position < numHeaders) {//是头部
return;
}
//adapter body
final int adjPosition = position - numHeaders;
int adapterCount = 0;
if (mAdapter != null) {
adapterCount = mAdapter.getItemCount();
if (adjPosition < adapterCount) {
mAdapter.onBindViewHolder(holder, adjPosition);
return;
}
}
}
@Override
public int getItemViewType(int position) {
//判断当前条目是什么类型的---决定渲染什么视图给什么数据
int numHeaders = getHeadersCount();
if (position < numHeaders) {//是头部
return RecyclerView.INVALID_TYPE;
}
//正常条目部分
// Adapter
final int adjPosition = position - numHeaders;
int adapterCount = 0;
if (mAdapter != null) {
adapterCount = mAdapter.getItemCount();
if (adjPosition < adapterCount) {
return mAdapter.getItemViewType(adjPosition);
}
}
//footer部分
return RecyclerView.INVALID_TYPE - 1;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//header
if (viewType == RecyclerView.INVALID_TYPE) {
return new HeaderViewHolder(mHeaderViewInfos.get(0));
} else if (viewType == RecyclerView.INVALID_TYPE - 1) {//footer
return new HeaderViewHolder(mFooterViewInfos.get(0));
}
return mAdapter.onCreateViewHolder(parent, viewType);
}
public int getHeadersCount() {
return mHeaderViewInfos.size();
}
public int getFootersCount() {
return mFooterViewInfos.size();
}
private static class HeaderViewHolder extends RecyclerView.ViewHolder {
public HeaderViewHolder(View view) {
super(view);
}
}
}
我们footerView和headerView的Adapter封装好了,接下来肯定也要重新改造下RecyclerView这个类,打造能接收HeaderView和FooterView的RecyclerView:
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;
import java.util.ArrayList;
public class WrapRecyclerView extends RecyclerView {
private ArrayList<View> mHeaderViewInfos = new ArrayList<View>();
private ArrayList<View> mFooterViewInfos = new ArrayList<View>();
private Adapter mAdapter;
public WrapRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void addHeaderView(View v) {
mHeaderViewInfos.add(v);
// Wrap the adapter if it wasn't already wrapped.
if (mAdapter != null) {
if (!(mAdapter instanceof WrapRecyclerViewAdapter)) {
mAdapter = new WrapRecyclerViewAdapter(mHeaderViewInfos, mFooterViewInfos, mAdapter);
}
}
}
public void addFooterView(View v) {
mFooterViewInfos.add(v);
// Wrap the adapter if it wasn't already wrapped.
if (mAdapter != null) {
if (!(mAdapter instanceof WrapRecyclerViewAdapter)) {
mAdapter = new WrapRecyclerViewAdapter(mHeaderViewInfos, mFooterViewInfos, mAdapter);
}
}
}
@Override
public void setAdapter(Adapter adapter) {
if (mHeaderViewInfos.size() > 0 || mFooterViewInfos.size() > 0) {
mAdapter = new WrapRecyclerViewAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);
} else {
mAdapter = adapter;
}
super.setAdapter(mAdapter);
}
}
ok接下来添加完整布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.fly.rv02.MainActivity">
<com.fly.rv02.WrapRecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
在代码中添加头部和尾部:
View headerView = View.inflate(this, R.layout.header, null);
mRecyclerView.addHeaderView(headerView);
View footerView = View.inflate(this, R.layout.footer, null);
mRecyclerView.addFooterView(footerView);
两个布局过于简单就不贴了,下面看效果:
大功告成,大家赶紧去尝试一下吧!!!