一.概述
google提供的SwipeRefreshLayout只具有下拉刷新的效果,而我们平常的需求都是既要有下拉刷新又要支持上啦加载的.一个偶然的机会看一篇利用NestedScrolling机制改造SwipeRefreshLayout,这篇文章详细的讲解了如何让SwipeRefreshLayout支持上啦加载,但是效果有点美中不足,只有加载的圆圈进度条,没有加载错误和到底了的ui显示,于是就在他的基础上加工了一下,建议先去看看他的文章再来看这篇,先上个效果图.
二.如何使用
为了方便使用,我将这个库上传到了jcenter上,所以使用as的朋友就很简单了只要加上 compile ‘swipeRefreshAndLoad:swipeRefreshAndLoad:0.0.1’既可.
然后在activity按下面的方式使用即可
//设置下拉刷新的进度条颜色
refreshLayout.setColorSchemeColors(Color.YELLOW,Color.RED,Color.GREEN,Color.BLUE);
refreshLayout.setOnRefreshListener(new SwipeRefreshAndLoad.OnRefreshListener() {
@Override
public void onRefresh() {
//hd是 handler
hd.sendEmptyMessageDelayed(0,3000);
}
});
//设置上啦加载的进度条颜色
refreshLayout.setBottomColorSchemeColors(Color.GREEN,Color.BLUE,Color.YELLOW,Color.RED);
//在这里新增上啦加载的回调
refreshLayout.setOnBottomRefreshListenrer(new SwipeRefreshAndLoad.OnBottomRefreshListener() {
@Override
public void onBottomRefresh() {
hd.sendEmptyMessageDelayed(1,3000);
}
});
//handler的代码
Handler hd = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0:
if(refreshLayout.isRefreshing())
//停止刷新
refreshLayout.setRefreshing(false);
break;
case 1:
//停止上啦加载
refreshLayout.setBottomRefreshing(false);
//设置加载错误的点击事件
refreshLayout.setError(new View.OnClickListener() {
@Override
public void onClick(View v) {
refreshLayout.setBottomRefreshing(true);
}
});
break;
}
}
};
三.分析一下如何添加底部的UI
我这里只是原来作者的代码上添加一下代码,所以最好是先去看一下原来作者的分析.
1.首先在在构造方法中添加view
bottomLoadView = new RelativeLayout(getContext());
bottomLoadView.setBackgroundColor(Color.rgb(220, 220, 220));
bottomLoadView.setGravity(Gravity.CENTER);
mTvLoad = new TextView(getContext());
mTvLoad.setText("没有更多数据了!");
bottomLoadView.addView(mTvLoad);
addView(bottomLoadView);
2.在onmeasure中测量view
bottomLoadView.measure(widthMeasureSpec,
MeasureSpec.makeMeasureSpec((int) (48 * metrics.density), MeasureSpec.EXACTLY));
3.在onlayout方法中布置改view显示的位置
让view显示在屏幕底下
bottomLoadView.layout(childLeft, childHeight, bottomLoadView.getMeasuredWidth() - getPaddingRight(), childHeight + bottomLoadView.getMeasuredHeight());
4.新增以下方法
/**
* 设置没有数据了
*/
public void setNoMore() {
mTvLoad.setText("没有更多数据了!");
//将底部没有更多数据的ui显示出来
scrollTo(0, bottomLoadView.getMeasuredHeight());
bottomLoadView.setOnClickListener(null);
}
/**
* 加载失败
*/
public void setError(OnClickListener onClickListener) {
mTvLoad.setText("点击重试!");
//将底部加载失败的ui显示出来
scrollTo(0, bottomLoadView.getMeasuredHeight());
bottomLoadView.setOnClickListener(new MyClickListener(onClickListener));
}
class MyClickListener implements OnClickListener {
private OnClickListener clickListener;
public MyClickListener(OnClickListener clickListener) {
this.clickListener = clickListener;
}
@Override
public void onClick(View v) {
if (clickListener != null) {
scrollTo(0, 0);
clickListener.onClick(v);
}
}
}
//重写这个方法
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
downY = (int) ev.getY();
break;
case MotionEvent.ACTION_MOVE:
int moveY = (int) (ev.getY() - downY);
int scrollY = getScrollY();
int height = bottomLoadView.getMeasuredHeight();
//如果是下拉,就先将底部view还原
if (moveY > 0) {
if (scrollY <= height && scrollY > 0) {
if (scrollY - moveY > height) {
moveY = scrollY - height;
}
if (scrollY - moveY < 0) {
moveY = 0 - scrollY;
}
scrollBy(0, -moveY);
}
}
downY = (int) ev.getY();
break;
case MotionEvent.ACTION_UP:
break;
}
return super.dispatchTouchEvent(ev);
}
四.总结
虽然是在原来的继承上做一点小改动,但是效果还是挺好的,以后在项目中多使用,看看还有哪些地方需要改进的,项目的github地址SwiepRefreshAndLoad