添加头布局和脚步:
只要是用过RecyclerView的估计大家都知道,这个东西不像ListView那样直接可以
- addHeaderView()或addFooterView(),removeHeaderView(),removeFooterView()
所以今天就进入我们的正题,一千人就有一千个哈姆雷特,给RecyclerView添加头的方式各有各的方式:就我目前所见:基本类似就是三种: - 上边用一个垂直的LinearLayout 里面动态的添加或者移除l
- 模仿ListView的添加头的方法,如果是这种就要去看ListView的源码了,不过我觉得这种添加方式不是特别好,只是个人建议,因为你还得去重写recyclerview,感觉还是稍稍的的有嗲麻烦
- 第三种,也是我接下我要写的这一种装饰者模式添加头,给这个对象额外的增加功能:
一不开心就上代码:
/**
* Created by fx on 2017/6/29.
* 采用装饰着模式进行封装头部和尾部:
*/
public class HeaderAndFooterWrapper<k> extends RecyclerView.Adapter<BaseViewHolder> {
private static final int BASE_ITEM_TYPE_HEADER = 100000;
private static final int BASE_ITEM_TYPE_FOOTER = 200000;
private SparseArray<View> mHeaderViews = new SparseArray<>();
private SparseArray<View> mFootViews = new SparseArray<>();
private BaseAdapter<k> mInnerAdapter;
private static final int M_DEFAULT_NUMBER = -1;
private static final String TAG = "HeaderAndFooterWrapper";
//将我们自己的adapter 传进去:
public HeaderAndFooterWrapper(BaseAdapter<k> adapter) {
mInnerAdapter = adapter;
}
@Override
public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
BaseViewHolder holder;
if (mHeaderViews.get(viewType) != null) {
holder = BaseViewHolder.creatBaseViewHolder(mHeaderViews.get(viewType));
return holder;
} else if (mFootViews.get(viewType) != null) {
holder = BaseViewHolder.creatBaseViewHolder(mFootViews.get(viewType));
return holder;
}
return mInnerAdapter.onCreateViewHolder(parent, viewType);
}
@Override
public void onBindViewHolder(BaseViewHolder viewHolder, int position) {
if (isHeaderViewPos(position)) {
return;
}
if (isFooterViewPos(position)) {
return;
}
mInnerAdapter.onBindViewHolder(viewHolder, position - getHeadersCount());
}
@Override
public int getItemViewType(int position) {
if (isHeaderViewPos(position)) {
return mHeaderViews.keyAt(position);
} else if (isFooterViewPos(position)) {
return mFootViews.keyAt(position - getHeadersCount() - getRealItemCount());
}
return mInnerAdapter.getItemViewType(position - getHeadersCount());
}
private int getRealItemCount() {
return mInnerAdapter.getItemCount();
}
@Override
public int getItemCount() {
return getHeadersCount() + getFootersCount() + getRealItemCount();
}
private boolean isHeaderViewPos(int position) {
return position < getHeadersCount();
}
private boolean isFooterViewPos(int position) {
return position >= getHeadersCount() + getRealItemCount();
}
//add Headers 不重复添加头布局:
public void addHeaderView(View view) {
int i = mHeaderViews.indexOfValue(view);
if (M_DEFAULT_NUMBER == i) {
mHeaderViews.put(mHeaderViews.size() + BASE_ITEM_TYPE_HEADER, view);
}
}
public void addFootView(View view) {
int i = mFootViews.indexOfValue(view);
if (M_DEFAULT_NUMBER == i) {
mFootViews.put(mFootViews.size() + BASE_ITEM_TYPE_FOOTER, view);
}
}
public int getHeadersCount() {
return mHeaderViews.size();
}
public int getFootersCount() {
return mFootViews.size();
}
//针对网格布局:
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
mInnerAdapter.onAttachedToRecyclerView(recyclerView);
final RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
if (manager instanceof GridLayoutManager) {
((GridLayoutManager) manager).setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
//如果是头布局或者是脚布局返回为1;
int itemViewType = getItemViewType(position);
if (mHeaderViews.get(itemViewType) != null || mFootViews.get(itemViewType) != null) {
return ((GridLayoutManager) manager).getSpanCount();
}
return 1;
}
});
}
}
//针对流式布局
@Override
public void onViewAttachedToWindow(BaseViewHolder holder) {
mInnerAdapter.onViewAttachedToWindow(holder);
int layoutPosition = holder.getLayoutPosition();
if (isHeaderViewPos(layoutPosition) || isFooterViewPos(layoutPosition)) {
ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();
if (layoutParams != null) {
if (layoutParams instanceof StaggeredGridLayoutManager.LayoutParams) {
StaggeredGridLayoutManager.LayoutParams params = (StaggeredGridLayoutManager.LayoutParams) layoutParams;
//占领全部空间;
params.setFullSpan(true);
}
}
}
}
//remover header;
public boolean removedHeader(View view) {
int i = mHeaderViews.indexOfValue(view);
if (i == M_DEFAULT_NUMBER ) {
return false;
}
mHeaderViews.removeAt(i);
notifyItemRemoved(i);
return true;
}
//remover footer
public boolean removedFooter(View view) {
int i = mFootViews.indexOfValue(view);
if (i == M_DEFAULT_NUMBER ) {
return false;
}
mFootViews.removeAt(i);
notifyItemRemoved(i);
return true;
}
//remover all footerview;
public boolean removerAllFooterView() {
if (mFootViews.size() > 0) {
mFootViews.clear();
notifyDataSetChanged();
return true;
}
return false;
}
//remover all footerview;
public boolean removerAllHeaderView() {
if (mHeaderViews.size() > 0) {
mHeaderViews.clear();
notifyDataSetChanged();
return true;
}
return false;
}
}
在Activity里面直接这样使用
- 添加头
ComAdapter comAdapter = new ComAdapter(C.getList());
View view = mInflate.inflate(R.layout.header_view, (ViewGroup) mRecyView.getParent(), false);
HeaderAndFooterWrapper<String> emptyViewAdapter = new HeaderAndFooterWrapper<String>(comAdapter);
emptyViewAdapter.addHeaderView(view);
emptyViewAdapter.addFootView(view);
mRecyView.setAdapter(emptyViewAdapter);
///new HeaderAndFooterWrapper() 将当前的comAdapter 传入进去, 可以添加多个头布局和脚布局:
- 移移除单个头布局和单个脚布局
- removedHeader
- removedFooter
- 移除所有的头布局和脚布局
- removerAllHeaderView
- removerAllFooterView
总结:
终于写完了,是不是感觉用起来很简单,像之前的ListView 一样的 直接可以添加头,移除头 添加脚布局,移除脚布局;由于时间有限没有录gif视屏,后期一定补上, 废话也就不多说了,如果大家觉得我写的还不错,就抬起手给点个赞呗,如果有更好的或者觉得写的有问题的欢迎提问和骚扰
谢谢大家;