仿照Listview 优雅实现 RecyclerView的 HeaderView 和 FootView
来源:互联网 发布:包月无限流量软件 编辑:程序博客网 时间:2024/05/17 01:33
前言:
作为一个Listview的进阶产品 RecyclerView在很多时候使用起来并不是那么方便,而其中
addFootView
和addHeaderView
使用起来远没有 Listview的一句话来的简单,而目前大多数博文提供的思路都是在BaseAdapter
的ViewType
来做文章,这样做确实可以很好的实现我们想要的效果,而今天,我们就在这个基础上来进行一次封装,使得我们使用的方式变成下面这样
recyclerView.addFootView(R.layout.foot_item); recyclerView.addHeaderView(R.layout.header_item); recyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false)); recyclerView.setAdapter(adapter)
通过上面,我们大概能知道,我们是自定义了一个
RecyclerView
,其余的用法和原生的RecyclerView
是没有什么区别的,如果你感兴趣,那么,就接着往下看吧。。。
分析
上面的效果到底是怎么实现的呢?恩?聪明的你有没有想到
ListView
呢?然后你去翻看ListView
源码,我们可以发现,他的实现其实和我们想的应该是差不多的,通过一个HeaderViewListAdapter
将我们setAdapter
的适配器包裹起来,然后内部就可以通过我们的ViewType
来加载headerView
和FootView
了,恩?这叫什么模式来着。。。应该是装饰者模式。。。哈哈,原来如此简单,只是我们不容易想到而已,那么接下来,我们就来撸一把。。。
撸码
其实想到了这个方法,那么接下来的撸码过程应该是很简单的,这里我只考虑
LinearLayoutManager
这个布局管理器了,如果你要实现其他两种布局管理器的foot和header,可以去看看鸿洋大神的博客,Ok,多的不说了,直接贴代码。
import android.content.Context;import android.support.annotation.LayoutRes;import android.support.annotation.Nullable;import android.support.v7.widget.RecyclerView;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.ViewGroup;import java.util.ArrayList;import java.util.List;public class FootHeaderRecyclerView extends RecyclerView { //这里我们保存的是 layoutId 方便 createViewHolder List<Integer> mHeaders = new ArrayList<>(); List<Integer> mFoots = new ArrayList<>(); private Adapter mAdapter; public FootHeaderRecyclerView(Context context) { super(context); } public FootHeaderRecyclerView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } public FootHeaderRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public void addHeaderView(@LayoutRes int layoutId) { checkAdapter(); mHeaders.add(layoutId); } private void checkAdapter() { if (!(mAdapter == null || mAdapter instanceof AdapterWrapper)) { throw new IllegalStateException("please call addHeaderView or addFootView before setAdapter"); } } public void addFootView(@LayoutRes int layoutId) { checkAdapter(); mFoots.add(layoutId); } //关键在这里我们对 adapter 进行了包装 @Override public void setAdapter(Adapter adapter) { Adapter adapter1; if (mFoots.size() != 0 || mHeaders.size() != 0) { adapter1 = new AdapterWrapper(adapter); super.setAdapter(adapter1); } else { super.setAdapter(adapter); adapter1 = adapter; } mAdapter =adapter1; } private class AdapterWrapper extends Adapter { RecyclerView.Adapter adapter; public AdapterWrapper(Adapter adapter) { this.adapter = adapter; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); if (mHeaders.contains(viewType) || mFoots.contains(viewType)) { return new ViewHolder(inflater.inflate(viewType, parent, false)) { }; } else { return adapter.createViewHolder(parent, viewType); } } @Override public void onBindViewHolder(ViewHolder holder, int position) { //此处应该注意!!! // 和 listview 一样这里的 position 是包含了 foot 和 header 的 adapter.onBindViewHolder(holder, position); } @Override public int getItemCount() { return adapter.getItemCount() + mHeaders.size() + mFoots.size(); } //稍微有点障碍的可能就是这个 position 的计算了,当然,其实也很简单,代两个数进去计算就好了 @Override public int getItemViewType(int position) { if (position < mHeaders.size()) { //header size return mHeaders.get(position); } if (position >= mHeaders.size() && position < adapter.getItemCount() + mHeaders.size()) { return adapter.getItemViewType(position - mHeaders.size()); } if (position >= getItemCount() - mFoots.size()) { return mFoots.get(position - mHeaders.size() - adapter.getItemCount()); } throw new RuntimeException("unknown error position"); } }}
结束语
今天分享这个,应该算是最简单的,但也不能算是简单,如果不是带着问题去看了
ListView
的源码,我觉的我肯定是想不出这个方法来实现的,记得以前看源码,是为了看源码而看源码,往往看来看去,也不知所云,而带着某种目的或者疑问去看源码,就会发现,很多东西都变的清晰,变的有迹可循,最重要的你会发现,看源码再也不是枯燥无味的事情了,而是那么的吸引着你。。。好了,最后,还是希望本文对你有一点帮助
- 仿照Listview 优雅实现 RecyclerView的 HeaderView 和 FootView
- RecyclerView添加headerview和footview
- 在ListView中增加HeaderView和FootView
- Android 优雅的为RecyclerView添加HeaderView和FooterView
- Android 优雅的为RecyclerView添加HeaderView和FooterView
- Android 优雅的为RecyclerView添加HeaderView和FooterView
- Android 优雅的为RecyclerView添加HeaderView和FooterView
- Android 优雅的为RecyclerView添加HeaderView和FooterView
- Android 优雅的为RecyclerView添加HeaderView和FooterView
- Android 优雅的为RecyclerView添加HeaderView和FooterView
- Android 优雅的为RecyclerView添加HeaderView和FooterView
- Android 优雅的为RecyclerView添加HeaderView和FooterView
- Android 优雅的为RecyclerView添加HeaderView和FooterView
- Android 优雅的为RecyclerView添加HeaderView和FooterView
- Android 优雅的为RecyclerView添加HeaderView和FooterView
- Android 优雅的为RecyclerView添加HeaderView和FooterView
- Android 优雅的为RecyclerView添加HeaderView和FooterView
- Android 优雅的为RecyclerView添加HeaderView和FooterView
- Android 相关面试知识点整理
- OpenCV学习——读取usb摄像头或视频并按帧保存
- Copy List with Random Pointer (Frequent+)
- Greedy Match学习笔记一 —— 匹配原理及SAS实现
- POS机控件调用错误---Y5,与密码通讯失败
- 仿照Listview 优雅实现 RecyclerView的 HeaderView 和 FootView
- 新手学xingo golang服务器之-修改xingo 支持字符协议(一)
- TensorFlow关于 SSE AVX的Warning问题
- 修改Tomcat默认访问根目录
- 负值之美:负margin在页面布局中的应用
- 机器学习笔记:SVM
- AOP日志 记录方法参数名及对应值(包括对象和基本类型)
- PowerDesigner提示错误Non SQL Error : Could not load class com.mysql.jdbc.Driver
- JAVA注解的使用