概述
recyclerview 下拉刷新数据、滑动到最后一个item时加载更多。
只是为了实现功能,基本是对人家代码的修改。个人笔记。
借鉴了其它大神的
自定义RecyclerView实现下拉刷新和上拉加载
张鸿洋的
Android 优雅的为RecyclerView添加HeaderView和FooterView
RecyclerView 引入
compile 'com.android.support:recyclerview-v7:23.4.0'
recyclerView 有三种数据显示格式,这里遇到个问题,在第一、三模式下,item没有充满,header也实质上是item,网上的说的原因是:
View.inflate(mContext, R.layout.item_layout, null);
必须要换成下面的构造方式把parent带进去:
LayoutInflater.from(mContext).inflate(R.layout.item_layout, parent, false);
但我问题是:
recyclerView 的父控件是ConstraintLayout
//线性 类listview
recyclerview.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
//类 gridview
recyclerview.setLayoutManager(new GridLayoutManager(this,2));
//瀑布流显示
recyclerview.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
重写RecyclerView
这是我对于第一个借鉴的代码修改,处理了一些细节上的问题。
大体的思路:
1.onTouch 来控制下拉刷新,通过layoutManager来得到第一个显示的item,第一个的话下拉时对添加的header设置paddingTop,默认的paddingTop是 - header.getHeight,得到隐藏的效果。通过滑动的距离分三种状态,正在刷新、下拉中、放开刷新。
这样只有在手动滑动的时都会触发。
2.OnScrollListener来控制加载更多,也不用考虑惯性滑动。
3.这里layoutManager,LinearLayoutManager和GridLayoutManager与StaggeredGridLayoutManager是不同的在取显示item时。
4.这里header直接添加多个没有问题,Footer不行,可以再套一层。
public class RefreshRecyclerView extends RecyclerView {
private Context mContext;
// 顶部视图,下拉刷新控件
private LinearLayout headerView;
// 正在刷新状态的进度条
private ProgressBar pb_header_refresh;
// 刷新箭头
private ImageView iv_header_refresh;
// 显示刷新状态
private TextView tv_status;
// 显示最近一次的刷新时间
private TextView tv_time;
// 转到下拉刷新状态时的动画
private RotateAnimation downAnima;
// 转到释放刷新状态时的动画
private RotateAnimation upAnima;
// 尾部视图
private View footerView;
// 尾部(上拉加载控件)的高度
private int footerViewHeight;
//触摸事件中按下的Y坐标,初始值为-1,为防止ACTION_DOWN事件被抢占
private float startY = -1;
// 下拉刷新控件的高度
private int pulldownHeight;
// 刷新状态:下拉刷新
private final int PULL_DOWN_REFRESH = 0;
// 刷新状态:释放刷新
private final int RELEASE_REFRESH = 1;
// 刷新状态:正常刷新
private final int REFRESHING = 2;
// 当前头布局的状态-默认为下拉刷新
private int currState = PULL_DOWN_REFRESH;
// 刷新事件的回调
private RefreshRecyclerView.OnRefreshListener mOnRefreshListener;
// 判断是否是加载更多
private boolean isLoadingMore;
// StaggeredGridLayoutManager
private int[] lastPositions;
//是否需要刷新
private boolean isNeedLoadingMore = true;
private boolean isNeedRefresh = true;
public RefreshRecyclerView(Context context) {
this(context, null);
}
public RefreshRecyclerView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RefreshRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mContext = context;
initHeaderView();
initFooterView();
}
/**
* 是否加载更多
*
* @param enable
*/
public void setPullLoadEnable(boolean enable) {
isNeedLoadingMore = enable;
}
/**
* 是否刷新
*
* @param enable
*/
public void setPullRefreshEnable(boolean enable) {
isNeedRefresh = enable;
}
/**
* 返回尾部布局,供外部调用
*
* @return
*/
public View getFooterView() {
return footerView;
}
/**
* 返回头部布局,供外部调用
*
* @return
*/
public View getHeaderView() {
return headerView;
}
/**
* 通过HeaderAndFooterWrapper对象给RecyclerView添加尾部
*
* @param footerView