使用过 SwipeRefreshLayout 的都知道,这个控件谷歌只添加下拉刷新,如果需要上拉加载,就需要自己去实现,这里是结合RecyclerView添加了上拉加载功能,列出代码仅供参考。
这里是SwipeRefreshLoadLayout源码:
/**
* @author ttarfall
* @date 2016-03-25 12:32
*/
public class SwipeRefreshLoadLayout extends SwipeRefreshLayout {
private static final String TAG = "SwipeRefreshLoadLayout";
/**
* 滑动到最下面时的上拉操作 有效距离
*/
private int mTouchSlop;
private RecyclerView recyclerView;
/**
* 刷新回调接口
*/
private OnRefreshListener mListener;
/**
* 上拉加载回调接口
*/
private OnLoadListener onLoadListener;
private float downY, lastY;
/**
* 是否在加载中 ( 上拉加载更多 )
*/
private boolean isLoading = false;
/**
* 设置是否支持自动加载 默认不支持
*/
private boolean mIsAutoLoad = false;
/**
* 支持自动上拉加载触发的有效行数
*/
private int autoLoadCount = 1;
/**
* 自动刷新线程
*/
private Runnable autoRefreshRunnable;
/**
* 加载数据线程
*/
private Runnable loadDataRunnable;
public SwipeRefreshLoadLayout(Context context) {
this(context, null);
}
public SwipeRefreshLoadLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
getView();
setColorSchemeColors(getResources().getColor(R.color.bg_orange_red));
}
/**
* 设置加载状态
*
* @param isLoading
*/
public void setIsLoading(boolean isLoading) {
this.isLoading = isLoading;
}
/**
* 是否正在加载中
*
* @return
*/
public boolean isLoading() {
return isLoading;
}
/**
* 设置是否自动上拉加载
*
* @param isAutoLoad
*/
public void setAutoLoad(boolean isAutoLoad) {
mIsAutoLoad = isAutoLoad;
}
@Override
public void setOnRefreshListener(OnRefreshListener listener) {
super.setOnRefreshListener(listener);
mListener = listener;
}
/**
* 默认等待时间
*/
private static final long DEFAULT_DELAYMILLIS = 300;
/**
* 自动下拉刷新
*/
public void setAutoRefreshing() {
setAutoRefreshing(DEFAULT_DELAYMILLIS);
}
/**
* 启动自动刷新
*
* @param delayMillis
*/
private void setAutoRefreshing(final long delayMillis) {
if (autoRefreshRunnable == null && !isRefreshing() && !isLoading) {//启动自动刷新,前提是界面不处于刷新中和加载中
autoRefreshRunnable = new Runnable() {
@Override
public void run() {
int height = getHeight();
if (height > 0) {//只有视图创建以后,高度才会大于0,因此在视图创建以后再发起自动刷新
if (mListener != null) {
setRefreshing(true);
mListener.onRefresh();
}
} else {
setAutoRefreshing(delayMillis);
}
}
};
}
handler.postDelayed(autoRefreshRunnable, delayMillis);
}
public void setRefreshing(boolean refreshing) {
if (isLoading) {
super.setRefreshing(false);
} else {
super.setRefreshing(refreshing);
getView();
if (recyclerView != null) {
RecyclerView.Adapter a = recyclerView.getAdapter();
if (a instanceof BaseLoadAdapter) {
((BaseLoadAdapter) a).setLoading(false);
}
}
}
}
private void getView() {
//当RecyclerView视图为空,并且使用了上拉加载监听回调才获取视图
if (recyclerView == null && onLoadListener != null) {
getView(this);
}
}
private void getView(View viewParent) {
if (viewParent instanceof ViewGroup) {
int count = ((ViewGroup) viewParent).getChildCount();
for (int i = 0; i < count; i++) {
View view = ((ViewGroup) viewParent).getChildAt(i);
if (view instanceof RecyclerView) {
recyclerView = (RecyclerView) view;
RecyclerView.Adapter a = recyclerView.getAdapter();
if (a instanceof BaseLoadAdapter)
((BaseLoadAdapter) a).setSwipeRefreshLoadLayout(this);
break;
} else {
getView(view);
}
}
}
}
public void setOnLoadListener(OnLoadListener onLoadListener) {
this.onLoadListener = onLoadListener;
}
public OnLoadListener getOnLoadListener() {
return onLoadListener;
}
/**
* 判断是否到了最底部
*/
private boolean isBottom() {
getView();
if (recyclerView != null) {
RecyclerView.Adapter a = recyclerView.getAdapter();
RecyclerView.LayoutManager m = recyclerView.getLayoutManager();
if (m instanceof LinearLayoutManager) {
LinearLayoutManager lm = (LinearLayoutManager) m;
if (mIsAutoLoad) {
return lm.findLastCompletelyVisibleItemPosition() > a.getItemCount() - autoLoadCount;
} else {
return lm.findLastCompletelyVisibleItemPosition() == a.getItemCount() - 1;
}
}
}
return false;
}
/**
* 设置触发自动上拉加载的有效行数
*
* @param count
*/
public void setAutoLoadCount(int count) {
if (count < 1) {
return;
}
if (!mIsAutoLoad) {
mIsAutoLoad = !mIsAutoLoad;
}
autoLoadCount = count;
}
public int getAutoLoadCount() {
return autoLoadCount;
}
/**
* 是否是上拉操作
*
* @return
*/
private boolean isPullUp() {
return (downY - lastY) >= mTouchSlop;
}
/**
* 是否可以加载更多, 条件是到了最底部, View不在加载中, 且为上拉操作, 并且不是下拉刷新
*
* @return
*/
private boolean canLoad() {
return isBottom() && !isLoading && isPullUp() && !isRefreshing();
}
private int msgCount = 0;
private boolean isCountineMove = false;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MotionEvent.ACTION_MOVE:
if (msgCount == 1) {
if (!isLoading && onLoadListener != null) {//当正在load不在进入执行
if (isPullUp()) {
getView();
if (recyclerView != null) {
RecyclerView.Adapter a = recyclerView.getAdapter();
if (a instanceof BaseLoadAdapter) {
((BaseLoadAdapter) a).setLoadBefore();
}
}
}
}
msgCount = 0;
} else {
if (msgCount > 0) {
msgCount--;
} else {
msgCount = 0;
}
}
break;
case MotionEvent.ACTION_UP:
if (!isCountineMove) {
if (!isLoading && onLoadListener != null) {//当正在load不在进入执行
if (canLoad()) {
msgCount = 0;//如果开始加重下一页,msgCount为0
loadData();
}
}
}
break;
default:
break;
}
super.handleMessage(msg);
}
};
private long historyTime = 0;
/**
* 是否可以发送消息
*
* @return
*/
private boolean isSendMessage() {
long curTime = System.currentTimeMillis();
if (curTime - historyTime > 500) {
historyTime = curTime;
return true;
} else {
return false;
}
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
if (!isLoading && onLoadListener != null) {//当正在load不在进入执行
downY = ev.getY();
}
break;
case MotionEvent.ACTION_MOVE:
if (!isLoading && onLoadListener != null && isSendMessage()) {
isCountineMove = true;
msgCount++;
LogUtil.i("action=" + MotionEvent.ACTION_MOVE + ", msgCount=" + msgCount);
lastY = ev.getY();
Message msg = new Message();
msg.what = MotionEvent.ACTION_MOVE;
handler.sendMessageDelayed(msg, 500);
}
break;
case MotionEvent.ACTION_UP:
if (!isLoading && onLoadListener != null) {
isCountineMove = false;
LogUtil.i("action=" + MotionEvent.ACTION_MOVE + ", msgCount=" + msgCount);
lastY = ev.getY();
Message msg = new Message();
msg.what = MotionEvent.ACTION_UP;
handler.sendMessageDelayed(msg, 500);
}
break;
default:
break;
}
return super.dispatchTouchEvent(ev);
}
/**
* @param loading
*/
public void setLoading(boolean loading) {
isLoading = loading;
if (!isLoading) {
downY = 0;
lastY = 0;
}
getView();
if (recyclerView != null) {
RecyclerView.Adapter a = recyclerView.getAdapter();
if (a instanceof BaseLoadAdapter) {
((BaseLoadAdapter) a).setLoading(loading);
}
}
}
/**
* 如果到了最底部,而且是上拉操作.那么执行onLoad方法
*/
private void loadData() {
DebugUtil.i(TAG, "loadData 方法执行");
if (onLoadListener != null) {
// 设置状态
setLoading(true);
if (loadDataRunnable == null)
loadDataRunnable = new Runnable() {
@Override
public void run() {
onLoadListener.onLoad();
}
};
handler.postDelayed(loadDataRunnable, 500);
} else {
setLoading(false);
}
}
/**
* 加载更多的监听器
*
* @author mrsimple
*/
public interface OnLoadListener {
public void onLoad();
}
}