RecyclerView添加头部(addHeaderView)和脚部(addFooterView)的封装
来源:互联网 发布:android 彩票app源码 编辑:程序博客网 时间:2024/06/08 07:40
RecyclerView的功能强大之处就不用说了,但是相比于listview来说,它也有些小缺点,比如:没有了间隔线divider,没有addHeaderView、addFooterView等方法,所以用起来不是那么方便。今天主要完成RecyclerView的addHeaderView和addFooterView方法。
运行效果如下:
第一步:自定义RecyclerView,代码如下:
public class XRecyclerView extends RecyclerView { //用来存储添加的headerView和footerView private ArrayList<View> mHeadView = new ArrayList<>(); private ArrayList<View> mFootView = new ArrayList<>(); //RecyclierView的适配器 private Adapter mAdapter; public XRecyclerView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } //添加头部view,仿ListView的源码改造 public void addHeaderView(View headerView) { mHeadView.add(headerView); if (mAdapter != null) { if (!(mAdapter instanceof HeaderViewRecyclerAdapter)) { mAdapter = new HeaderViewRecyclerAdapter(mHeadView,mFootView, mAdapter); } } } //添加脚View public void addFooterView(View footView) { mFootView.add(footView); if (mAdapter != null) { if (!(mAdapter instanceof HeaderViewRecyclerAdapter)) { mAdapter = new HeaderViewRecyclerAdapter(mHeadView,mFootView, mAdapter); } } } @Override public void setAdapter(Adapter adapter) { //参考listview方法 setAdapter的源码,对adapter进行更换 if (mHeadView.size() > 0 || mFootView.size() > 0) mAdapter = new HeaderViewRecyclerAdapter(mHeadView, mFootView, adapter); else { mAdapter = adapter; } super.setAdapter(mAdapter); }}
第二步自定义RecyclerView的adapter,代码如下:
public class HeaderViewRecyclerAdapter extends RecyclerView.Adapter { private final int HEADER = 1; private final int FOOTER = 2; private ArrayList<View> mHeadView; private ArrayList<View> mFootView; private RecyclerView.Adapter mAdapter; public HeaderViewRecyclerAdapter(ArrayList<View> HeadView, ArrayList<View> FootView, RecyclerView.Adapter adapter) { mAdapter = adapter; if (HeadView == null) { //为了防止空指针异常 mHeadView = new ArrayList<>(); } else { mHeadView = HeadView; } if (FootView == null) { mFootView = new ArrayList<>(); } else { mFootView = FootView; } } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { //头部修改newHeadViewHolder的方法,mFooterView,有几个头,就需要几个headViewHolder if (viewType == HEADER) { return new HeadViewHolder(mHeadView.get(0)); } else if (viewType == FOOTER) { //脚部,修改newHeadViewHolder的方法,mFooterView,有多个 return new FootViewHolder(mFootView.get(0)); } //body部分,暴露出去操作 return mAdapter.onCreateViewHolder(parent, viewType); } //判断view的类型,头,身体,脚 @Override public int getItemViewType(int position) { int headcount = getHeadCount(); //返回头部 if (position < headcount) { //返回头部类型, return HEADER; } //body类型 final int midPosition = position - headcount; int itemCount = 0; if (mAdapter != null) { itemCount = mAdapter.getItemCount(); if (midPosition < itemCount) { //返回type不要写死了,body的类型可能不一致 return mAdapter.getItemViewType(midPosition); } } //Footer类型 return FOOTER; } /** * 和数据绑定,这里只做body部分的绑定 * 头和脚的数据绑定逻辑都是在外部操作的 * 传入前都已经绑定好l */ @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { int headcount = getHeadCount(); if (position < headcount) { //头部数据绑定,外部传入前已经操作,这里不再操作 return; } //body数据绑定 final int midPosition = position - headcount; int itemcount = 0; if (mAdapter != null) { itemcount = mAdapter.getItemCount(); if (midPosition < itemcount) { //暴露出去自由操作,传入的是调整后的位置,而不是算上头角的位置// mAdapter.onBindViewHolder(holder, position); mAdapter.onBindViewHolder(holder, midPosition); return; } } //脚部数据绑定,和头一样,啥也不用操作 } @Override public int getItemCount() { //身体部分不为空 if (mAdapter != null) { return getHeadCount() + getFootCount() + mAdapter.getItemCount(); } else { //只有头和脚的情况下 return getHeadCount() + getFootCount(); } } private int getFootCount() { return mFootView.size(); } public int getHeadCount() { return mHeadView.size(); } /** * 面两个head viewholder 没什么卵用 * viewholder是为了相同的item减少findviewbyid的时间 * 头部holder和尾部holder没有共性的findviewbyid * 为了拓展方便只得创建,但是不会用到 */ class HeadViewHolder extends RecyclerView.ViewHolder { public HeadViewHolder(View itemView) { super(itemView); } } class FootViewHolder extends RecyclerView.ViewHolder { public FootViewHolder(View itemView) { super(itemView); } }}
第三步,就是在activity中使用刚才写的recyclerview,代码如下:
public class MainActivity extends AppCompatActivity { private XRecyclerView recyclerView; private List<String> list = new ArrayList<>(); private View headView; private View footView; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); recyclerView = ((XRecyclerView) findViewById(R.id.recyclerView)); initData(); initHeaderView(); recyclerView.addHeaderView(headView); recyclerView.addFooterView(footView); MyAdapter adapter = new MyAdapter(list); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(adapter); } private void initHeaderView() { headView = LayoutInflater.from(this).inflate(R.layout.header, null); footView = LayoutInflater.from(this).inflate(R.layout.footer, null); } private void initData() { for (int i = 0; i < 10; i++) { list.add("我是身体body" + i); } } class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> { private List<String> list; public MyAdapter(List<String> list) { this.list = list; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = LayoutInflater.from(MainActivity.this).inflate(R.layout.item, parent, false); MyViewHolder holder = new MyViewHolder(itemView); return holder; } @Override public void onBindViewHolder(MyViewHolder holder, int position) { holder.text.setText(list.get(position)); } @Override public int getItemCount() { return list.size(); } class MyViewHolder extends RecyclerView.ViewHolder { TextView text; public MyViewHolder(View itemView) { super(itemView); text = (TextView) itemView.findViewById(R.id.tv_item); } } }}
总结:这种方法只能添加一个头和一个脚,本来是想能任意添加头和脚的,后来发现有点问题,
if (viewType == HEADER) { return new HeadViewHolder(mHeadView.get(0)); } else if (viewType == FOOTER) { //脚部,修改newHeadViewHolder的方法,mFooterView,有多个 return new FootViewHolder(mFootView.get(0)); } //body部分,暴露出去操作 return mAdapter.onCreateViewHolder(parent, viewType);
在viewholder创建的时候,头部和尾部也有viewholder,这个对象池不能复用,因为头和脚可以是各种不同类型的***,一旦添加多个头和脚的时候就有问题,这个问题待搞定。
2 0
- RecyclerView添加头部(addHeaderView)和脚部(addFooterView)的封装
- android listview addHeaderView和addFooterView的注意事项
- android listview addHeaderView和addFooterView的注意事项
- android listview addHeaderView和addFooterView的注意事项
- android listview addHeaderView和addFooterView的注意事项
- android listview addHeaderView和addFooterView的注意事项
- 可以addHeaderView和addFooterView的GridView
- android listview addHeaderView和addFooterView的注意事项
- android listview addHeaderView和addFooterView的注意事项
- android listview addHeaderView和addFooterView的注意事项
- android listview addHeaderView和addFooterView的注意事项
- ListView addHeaderView和addFooterView的注意事项
- android listview addHeaderView和addFooterView的注意事项
- 支持addHeaderView、 addFooterView、分页加载数据的RecyclerView
- 添加头部脚部RecyclerView
- RecyclerView中实现addHeaderView,addFooterView功能
- android listview addHeaderView和addFooterView
- listview的addHeaderView和addFooterView的几点笔记
- js 排序算法--冒泡算法
- 安卓多媒体应用-通知
- about unity3d freeze packaging assets sharedassets0.assets
- archlinux安装个简单桌面icewm
- prompt(1) to win writeup
- RecyclerView添加头部(addHeaderView)和脚部(addFooterView)的封装
- JAVA多线程之——Semaphore
- 因为 MyEclipse 和jdk不匹配问题
- 历届试题 回文数字
- 练习
- Java中的构造方法
- python基础知识之逗号输出、赋值
- python写map,reduce访问集群文件
- Activity启动流程分析