RecyclerView的上拉加载和下拉刷新
来源:互联网 发布:卡拉扬去世 知乎 编辑:程序博客网 时间:2024/06/05 18:48
recyclerview比较麻烦的是上拉加载更多功能,下拉刷新使用的是Google官方的SwipeRefreshLayout控件,实现起来非常简单。
一.上拉加载更多功能实际上就是给RecyclerView增加一个FooterView,然后通过判断是否滑动到了最后一条Item,来控制FooterView的显示和隐藏,接下来我们来看下如何实现:
public class LoadMoreAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private List<String> dataList; // 普通布局 private final int TYPE_ITEM = 1; // 脚布局 private final int TYPE_FOOTER = 2; // 当前加载状态,默认为加载完成 private int loadState = 2; // 正在加载 public final int LOADING = 1; // 加载完成 public final int LOADING_COMPLETE = 2; // 加载到底 public final int LOADING_END = 3; public LoadMoreAdapter(List<String> dataList) { this.dataList = dataList; } @Override public int getItemViewType(int position) { // 最后一个item设置为FooterView if (position + 1 == getItemCount()) { return TYPE_FOOTER; } else { return TYPE_ITEM; } } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { // 通过判断显示类型,来创建不同的View if (viewType == TYPE_ITEM) { View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.adapter_recyclerview, parent, false); return new RecyclerViewHolder(view); } else if (viewType == TYPE_FOOTER) { View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.layout_refresh_footer, parent, false); return new FootViewHolder(view); } return null; } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (holder instanceof RecyclerViewHolder) { RecyclerViewHolder recyclerViewHolder = (RecyclerViewHolder) holder; recyclerViewHolder.tvItem.setText(dataList.get(position)); } else if (holder instanceof FootViewHolder) { FootViewHolder footViewHolder = (FootViewHolder) holder; switch (loadState) { case LOADING: // 正在加载 footViewHolder.pbLoading.setVisibility(View.VISIBLE); footViewHolder.tvLoading.setVisibility(View.VISIBLE); footViewHolder.llEnd.setVisibility(View.GONE); break; case LOADING_COMPLETE: // 加载完成 footViewHolder.pbLoading.setVisibility(View.INVISIBLE); footViewHolder.tvLoading.setVisibility(View.INVISIBLE); footViewHolder.llEnd.setVisibility(View.GONE); break; case LOADING_END: // 加载到底 footViewHolder.pbLoading.setVisibility(View.GONE); footViewHolder.tvLoading.setVisibility(View.GONE); footViewHolder.llEnd.setVisibility(View.VISIBLE); break; default: break; } } } @Override public int getItemCount() { return dataList.size() + 1; } @Override public void onAttachedToRecyclerView(RecyclerView recyclerView) { super.onAttachedToRecyclerView(recyclerView); RecyclerView.LayoutManager manager = recyclerView.getLayoutManager(); if (manager instanceof GridLayoutManager) { final GridLayoutManager gridManager = ((GridLayoutManager) manager); gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { // 如果当前是footer的位置,那么该item占据2个单元格,正常情况下占据1个单元格 return getItemViewType(position) == TYPE_FOOTER ? gridManager.getSpanCount() : 1; } }); } } /** * 设置上拉加载状态 * * @param loadState 0.正在加载 1.加载完成 2.加载到底 */ public void setLoadState(int loadState) { this.loadState = loadState; notifyDataSetChanged(); }}
以上代码是自定义了recyclerview的适配器,定义了三种状态,分别是正在加载,加载完成以及滑动到底部,下面来看一下viewholder类的写法
private class RecyclerViewHolder extends RecyclerView.ViewHolder {
TextView tvItem;
RecyclerViewHolder(View itemView) {
super(itemView);
tvItem = (TextView) itemView.findViewById(R.id.tv_item);
}
}
private class FootViewHolder extends RecyclerView.ViewHolder {
ProgressBar pbLoading;
TextView tvLoading;
LinearLayout llEnd;
FootViewHolder(View itemView) {
super(itemView);
pbLoading = (ProgressBar) itemView.findViewById(R.id.pb_loading);
tvLoading = (TextView) itemView.findViewById(R.id.tv_loading);
llEnd = (LinearLayout) itemView.findViewById(R.id.ll_end);
}
}
}
首先定义了布局和数据加载状态的一些标志,然后在getItemViewType方法中设置最后一个Item为FooterView,在onCreateViewHolder方法中根据viewType来加载不同的布局,最后在onBindViewHolder方法中设置一下加载的状态显示就OK了,由于多了一个FooterView,所以要记得在getItemCount方法的返回值中加上1。
二. 到这里一个线性布局列表的Adapter就完成了,但是我们的recyclerview在实际的使用中还经常使用到网格布局,针对网格布局,我们要再增加一些处理
@Overridepublic void onAttachedToRecyclerView(RecyclerView recyclerView) { super.onAttachedToRecyclerView(recyclerView); RecyclerView.LayoutManager manager = recyclerView.getLayoutManager(); if (manager instanceof GridLayoutManager) { final GridLayoutManager gridManager = ((GridLayoutManager) manager); gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { // 如果当前是footer的位置,那么该item占据2个单元格,正常情况下占据1个单元格 return getItemViewType(position) == TYPE_FOOTER ? gridManager.getSpanCount() : 1; } }); }}
在Adapter中重写onAttachedToRecyclerView方法,首先判断当前是否为网格布局,然后给GridLayoutManager设置一个SpanSizeLookup,这是一个抽象类,里面有一个抽象方法getSpanSize,这个方法的返回值决定了每个Item占据的单元格数。
如果我们实现的是一个两列的网格布局,那么当前Item是FooterView的话需要占据两个单元格才能横向充满屏幕,所以需要返回2(GridLayoutManager的getSpanCount方法获取到的是当前一行中单元格的数量),正常情况下每个Item占据一个单元格。
- RecyclerView 下拉刷新和上拉加载
- RecyclerView的上拉加载,下拉刷新
- recyclerView的下拉刷新和上拉加载
- Android 实现RecyclerView的下拉刷新和上拉加载
- RecyclerView的上拉刷新,和下拉加载
- Recyclerview的下拉刷新和上拉加载
- RecyclerView的上拉加载和下拉刷新
- android 打造真正的下拉刷新上拉加载recyclerview(三):下拉刷新上拉加载
- android 打造真正的下拉刷新上拉加载recyclerview(三):下拉刷新上拉加载
- RecyclerView和SwipeRefreshLayout下拉刷新和上拉加载
- SwipeRefreshLayout和RecyclerView实现下拉刷新和上拉加载
- RecyclerView实现下拉刷新和上拉加载更多
- SwipeRefreshLayout + RecyclerView实现上拉加载和下拉刷新
- RecyclerView 下拉刷新和上拉加载(一)
- RecyclerView下拉刷新和上拉加载更多
- 自定义RecyclerView实现下拉刷新和上拉加载
- SwipeRefreshLayout + RecyclerView 实现 上拉刷新 和 下拉加载更多
- RecyclerView 添加下拉刷新和上拉加载更多
- Intellij IDEA设置忽略部分类编译错误
- 一点一点的积累算法JAVA版之插入排序
- 一个一百亿的计算器的实现
- 3分钟了解入门「机器学习」该学习什么?(下)
- 还原一个真实的马斯克:太空殖民时代的钢铁侠
- RecyclerView的上拉加载和下拉刷新
- Windows下编译WebRTC
- 关于SpringBoot的配置文件
- 【Java】如何用Java实现数据库查询
- maven的settings.xml配置文件详解
- js javascript 获取各种时间计算方法
- SSD-tensorflow:ValueError: number of input channels does not match corresponding dimension of filter
- 微信公众号h5牛牛源码搭建教程
- 抓取Android平台数据包之tcpdump 工具的使用过程中出现的问题