博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
RecyclerView添加头部和底部视图的实现
阅读量:6141 次
发布时间:2019-06-21

本文共 7065 字,大约阅读时间需要 23 分钟。

ListView是有addHeaderView和 addFooterView两个方法的.

但是作为官方推荐的ListView的升级版RecyclerView缺无法实现这两个方法。

那么如果使用RecyclerView实现这两个方法的效果该怎么做呢?

网上查询了很久,试过各种各样的实现方式,终于让我发现一个还不错的实现方法,那么就给大家推荐一下。

项目地址(别人写的,非博主的)

我看了下这个源码,很简单,即写了一个继承RecyclerView的控件,自己实现addHeaderView和addFooterView两个方法

package com.xqx.com.recyclerviewheaderdemo;import android.content.Context;import android.support.v7.widget.RecyclerView;import android.util.AttributeSet;import android.util.Log;import android.view.View;import android.view.ViewGroup;import java.util.ArrayList;import java.util.List;public class XCRecyclerView extends RecyclerView{    private ArrayList
mHeaderViews = new ArrayList<>(); private ArrayList
mFooterViews = new ArrayList<>(); private RecyclerView.Adapter mAdapter; private RecyclerView.Adapter mWrapAdapter; private static final int TYPE_HEADER = -101; private static final int TYPE_FOOTER = -102; private static final int TYPE_LIST_ITEM = - 103; public XCRecyclerView(Context context) { this(context, null); } public XCRecyclerView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public XCRecyclerView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context); } private void init(Context context){ } @Override public void setAdapter(Adapter adapter) { mAdapter = adapter; mWrapAdapter = new WrapAdapter(mHeaderViews, mFooterViews, adapter); super.setAdapter(mWrapAdapter); mAdapter.registerAdapterDataObserver(mDataObserver); } public void addHeaderView(View view){ mHeaderViews.clear(); mHeaderViews.add(view); } public void addFooterView(View view){ mFooterViews.clear(); mFooterViews.add(view); } public int getHeaderViewsCount(){ return mHeaderViews.size(); } public int getFooterViewsCount(){ return mFooterViews.size(); } private final RecyclerView.AdapterDataObserver mDataObserver = new RecyclerView.AdapterDataObserver() { @Override public void onChanged() { mWrapAdapter.notifyDataSetChanged(); } @Override public void onItemRangeChanged(int positionStart, int itemCount) { mWrapAdapter.notifyItemRangeChanged(positionStart, itemCount); }// @Override// public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {// mWrapAdapter.notifyItemRangeChanged(positionStart, itemCount, payload);// } @Override public void onItemRangeInserted(int positionStart, int itemCount) { mWrapAdapter.notifyItemRangeInserted(positionStart, itemCount); } @Override public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) { mWrapAdapter.notifyItemMoved(fromPosition, toPosition); } @Override public void onItemRangeRemoved(int positionStart, int itemCount) { mWrapAdapter.notifyItemRangeRemoved(positionStart, itemCount); } }; private class WrapAdapter extends RecyclerView.Adapter
{ private Adapter mAdapter; private List
mHeaderViews; private List
mFooterViews; public WrapAdapter(List
headerViews,List
footerViews,Adapter adapter){ this.mAdapter = adapter; this.mHeaderViews = headerViews; this.mFooterViews = footerViews; } public int getHeaderCount(){ return this.mHeaderViews.size(); } public int getFooterCount(){ return this.mFooterViews.size(); } public boolean isHeader(int position){ return position >= 0 && position < this.mHeaderViews.size(); } public boolean isFooter(int position){ return position < getItemCount() && position >= getItemCount() - this.mFooterViews.size(); } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if(viewType == TYPE_HEADER){ return new CustomViewHolder(this.mHeaderViews.get(0)); }else if(viewType == TYPE_FOOTER){ return new CustomViewHolder(this.mFooterViews.get(0)); }else{ return this.mAdapter.onCreateViewHolder(parent,viewType); } } @Override public void onBindViewHolder(ViewHolder holder, int position) { if(isHeader(position)) return; if(isFooter(position)) return; int rePosition = position - getHeaderCount(); int itemCount = this.mAdapter.getItemCount(); if(this.mAdapter != null){ if(rePosition < itemCount){ Log.v("czm","rePosition/itemCount="+rePosition+"/"+itemCount); this.mAdapter.onBindViewHolder(holder,rePosition); return; } } } @Override public long getItemId(int position) { if (this.mAdapter != null && position >= getHeaderCount()) { int rePosition = position - getHeaderCount(); int itemCount = this.mAdapter.getItemCount(); if (rePosition < itemCount) { return this.mAdapter.getItemId(rePosition); } } return -1; } @Override public int getItemViewType(int position) { if(isHeader(position)){ return TYPE_HEADER; } if(isFooter(position)){ return TYPE_FOOTER; } int rePosition = position - getHeaderCount(); int itemCount = this.mAdapter.getItemCount(); if(rePosition < itemCount){ return this.mAdapter.getItemViewType(position); } return TYPE_LIST_ITEM; } @Override public int getItemCount() { if(this.mAdapter != null){ return getHeaderCount() + getFooterCount() + this.mAdapter.getItemCount(); }else{ return getHeaderCount() + getFooterCount(); } } @Override public void registerAdapterDataObserver(AdapterDataObserver observer) { if(this.mAdapter != null){ this.mAdapter.registerAdapterDataObserver(observer); } } @Override public void unregisterAdapterDataObserver(AdapterDataObserver observer) { if(this.mAdapter != null){ this.mAdapter.unregisterAdapterDataObserver(observer); } } private class CustomViewHolder extends ViewHolder{ public CustomViewHolder(View itemView) { super(itemView); } } }}
XCRecyclerView

使用方法github里也写的清清楚楚的

private MyAdapter mAdapter;private XCRecyclerView mRecyclerView;private List
mData;private View mHeaderView;private View mFooterView;@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mData = new ArrayList
(); for(int i = 0; i < 10 ;i++){ mData.add("item_" + i); } mAdapter = new MyAdapter(mData); mRecyclerView = (XCRecyclerView) findViewById(R.id.recycler_view); mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); mHeaderView = LayoutInflater.from(this).inflate(R.layout.layout_header,mRecyclerView,false); mFooterView = LayoutInflater.from(this).inflate(R.layout.layout_footer,mRecyclerView,false); mRecyclerView.addHeaderView(mHeaderView); mRecyclerView.addFooterView(mFooterView); mRecyclerView.setAdapter(mAdapter);}

注意点:

addHeaderView之后 列表的数据坐标即相应发生变化!即addHeadView一次,列表第一个数据的下坐标+1(0-->1)

adapter.notifyItemChanged();等方法的坐标类似,都要相应的变化。

比如你addHeadView()一次

那么你想更新列表第4个列表项的视图,则adapter.notifyItemChanged(3+1);  多加1  headView也算一个列表项。 

转载地址:http://nhuya.baihongyu.com/

你可能感兴趣的文章
js 学习路线
查看>>
前端编辑工具有感
查看>>
CentOS6启动流程
查看>>
SpringBoot项目修改html后不即时编译
查看>>
mysql数据库的水平分表与垂直分表实例讲解
查看>>
OC 单例实现
查看>>
计算日期相隔天数/根据天数差计算结束日期
查看>>
iOS中RAC的使用
查看>>
MongonDB入门
查看>>
leetcode-506-Relative Ranks
查看>>
高并发编程必备基础(上)
查看>>
客户端HTTP缓存
查看>>
mysql server安装及配置
查看>>
一步一步学习SignalR进行实时通信_5_Hub
查看>>
[译] JavaScript 简明代码 —— 最佳实践
查看>>
win8.1恢复win7 CTRL+Space切换输入法
查看>>
强大的PHP一句话后门
查看>>
jquery中的prop方法和attr方法
查看>>
OWASP Top 10 2017年
查看>>
10.28T7 位运算+记忆化+DLZ常数剪枝
查看>>