我的下拉刷新是这么使用的
mPullRefreshView = (PullRefreshView) findViewById(R.id.pullRefreshView1);//先获取刷新的控件
mPullRefreshView.setContentView(new SXSRefreshContentView(getContext(), R.layout.frg_home1));//添加需要刷新的内容View
mPullRefreshView.setHeadView(new SXSRefreshHeadView(getContext()));//添加刷新的上部的View
mPullRefreshView.setPullRefresh(this);//添加刷新的回调
@Override
public void refresh(boolean isPullDown) {
//刷新回调true代表下拉刷新,false代表上拉加载
}
刷新成功失败以后别忘啦调用通知头部和顶部回去
mPullRefreshView.refreshSuccess("刷新成功");
mPullRefreshView.refreshFail("刷新失败");
xml布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.sxsfinance.SXS.view.refreshview.PullRefreshView
android:id="@+id/pullRefreshView1"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</com.sxsfinance.SXS.view.refreshview.PullRefreshView>
</LinearLayout>
这个是下拉刷新的主要实现代码
import android.content.Context;import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.widget.LinearLayout;
public class PullRefreshView extends LinearLayout implements Callback {
private PullRefresh pullRefresh;
private Handler handler;
/** 是否支持上拉加载 */
private boolean isUpRefresh = true;
/** 是否支持下拉刷新 */
private boolean isDownRefresh = true;
/** 刷新空间的高度 */
private double refresViewHeight = 0.1;
public PullRefreshView(Context context) {
super(context);
init();
}
public PullRefreshView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
setOrientation(VERTICAL);
handler = new Handler(this);
headView = new RefreshHeadView(getContext());
footView = new RefreshFootView(getContext());
contentView = new RefreshContentView(getContext());
addView();
}
private void addView() {
if (headView != null)
addView(headView);
if (contentView != null)
addView(contentView);
if (footView != null)
addView(footView);
}
public void addHeadView(int headView) {
if (this.headView != null) {
this.headView.removeAllViews();
this.headView.addView(LayoutInflater.from(getContext()).inflate(headView, null));
}
}
public void addFootView(int footView) {
if (this.footView != null) {
this.footView.removeAllViews();
this.footView.addView(LayoutInflater.from(getContext()).inflate(footView, null));
}
}
public void addContentView(int contentView) {
if (this.contentView != null) {
this.contentView.removeAllViews();
this.contentView.addView(LayoutInflater.from(getContext()).inflate(contentView, null));
}
}
/** 应该在addHeadView之前 */
public void setHeadView(RefreshHeadView headView) {
if (headView != null) {
this.headView = headView;
removeAllViews();
addView();
}
}
/** 应该在addFootView之前 */
public void setFootView(RefreshFootView footView) {
if (footView != null) {
this.footView = footView;
removeAllViews();
addView();
}
}
/** 应该在addContentView之前 */
public void setContentView(RefreshContentView contentView) {
if (contentView != null) {
this.contentView = contentView;
removeAllViews();
addView();
}
}
public void setPullRefresh(PullRefresh pullRefresh) {
this.pullRefresh = pullRefresh;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
/**
* 获得此ViewGroup上级容器为其推荐的宽和高,以及计算模式
*/
// int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
// int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
//
// // 计算出所有的childView的宽和高
// measureChildren(widthMeasureSpec, heightMeasureSpec);
if (headView != null && headView.getChildCount() > 0 && headView.getChildAt(0) != null) {
headView.getChildAt(0).measure(widthMeasureSpec,
MeasureSpec.makeMeasureSpec((int) (sizeHeight * refresViewHeight), heightMode));
}
if (contentView != null && contentView.getChildCount() > 0 && contentView.getChildAt(0) != null) {
contentView.getChildAt(0).measure(widthMeasureSpec, heightMeasureSpec);
}
if (footView != null && footView.getChildCount() > 0 && footView.getChildAt(0) != null) {
footView.getChildAt(0).measure(widthMeasureSpec,
MeasureSpec.makeMeasureSpec((int) (sizeHeight * refresViewHeight), heightMode));
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if (headView != null) {
headHeight = (int) (getHeight() * refresViewHeight);
headView.layout(0, -headHeight, r, 0);
if (headView.getChildCount() > 0 && headView.getChildAt(0) != null) {
headView.getChildAt(0).layout(0, 0, r, headHeight);
}
}
if (contentView != null) {
contentView.layout(l, t, r, b);
if (contentView.getChildCount() > 0 && contentView.getChildAt(0) != null) {
contentView.getChildAt(0).layout(l, t, r, b);
}
}
if (footView != null) {
footHeight = (int) (getHeight() * refresViewHeight);
footView.layout(l, b, r, b + footHeight);
if (footView.getChildCount() > 0 && footView.getChildAt(0) != null) {
footView.getChildAt(0).layout(l, 0, r, footHeight);
}
}
// initView();
}
/** 刷新控件的高度 */
public void setRefresViewHeight(double refresViewHeight) {
this.refresViewHeight = refresViewHeight;
}
/**
* 设置释放支持上拉加载
*/
public void setUpRefresh(boolean isUpRefresh) {
this.isUpRefresh = isUpRefresh;
}
/**
* 设置释放支持下拉刷新
*/
public void setDownRefresh(boolean isDownRefresh) {
this.isDownRefresh = isDownRefresh;
}
private RefreshHeadView headView;
private RefreshContentView contentView;
private RefreshFootView footView;
private float downY;
private float downX;
private float offetcY;
private float offetcX;
private float move = 0;
private int headHeight = 0;
private int footHeight = 0;
/** 是否处于刷新状态 */
private boolean refreshState = false;
private int mEvents = 0;
/** 标记当前是否为横向 0未确定方向,1,横向,2,纵向 */
private int direction = 0;
/** 内容锁定 */
private boolean isContentViewLock = false;
/**
* 当前状态 0,无状态,1,下拉状态,2,上拉状态
*/
private int state = 0;
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (refreshState)
return true;
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
downY = ev.getY();
downX = ev.getX();
mEvents = 0;
break;
case MotionEvent.ACTION_POINTER_DOWN:
case MotionEvent.ACTION_POINTER_UP:
// 过滤多点触碰
mEvents = -1;
break;
case MotionEvent.ACTION_MOVE:
if (mEvents != 0)
return true;
move = downY - ev.getY();
if (move > 0) {
move = (float) Math.pow(move, 0.87);
// move = (float) Math.pow(move, 1);
} else {
// move = (float) Math.pow(move, 1);
move = -(float) Math.pow(-move, 0.87);
}
offetcY = ev.getY() - downY;
offetcX = ev.getX() - downX;
if (direction == 0) {
if (offetcX * offetcX > offetcY * offetcY) {
if (offetcX * offetcX > 25)
direction = 1;
// 横向
} else {
if (offetcY * offetcY > 25)
direction = 2;
// 纵向
}
}
if (direction == 1 || direction == 0) {
move = 0;
return super.dispatchTouchEvent(ev);
}
if (headView == null && move < 0) {
downY = ev.getY();
move = 0;
}
if (footView == null && move > 0) {
downY = ev.getY();
move = 0;
}
// 控制按钮控制释放支持下拉刷新
if (!isDownRefresh && move < 0) {
downY = ev.getY();
move = 0;
}
// 控制按钮控制释放支持上拉加载
if (!isUpRefresh && move > 0) {
downY = ev.getY();
move = 0;
}
// 内容控件控制释放支持下拉刷新
if (contentView != null && !contentView.isDownRefresh() && move < 0 && state != 1) {
downY = ev.getY();
isContentViewLock = true;
move = 0;
}
// 内容空间控制释放支持上拉加载
if (contentView != null && !contentView.isUpRefresh() && move > 0 && state != 2) {
downY = ev.getY();
isContentViewLock = true;
move = 0;
}
if (isContentViewLock && move != 0) {
return super.dispatchTouchEvent(ev);
}
if (headView != null && headView instanceof PullListener) {
((PullListener) headView).pullDistance(-move, headHeight);
if (-move > headHeight) {
state = 1;
}
}
if (footView != null && footView instanceof PullListener) {
((PullListener) footView).pullDistance(move, footHeight);
if (move > footHeight) {
state = 2;
}
}
scrollTo(0, (int) move);
invalidate();
break;
case MotionEvent.ACTION_UP:
state = 0;
if (direction == 1) {
direction = 0;
isContentViewLock = false;
return super.dispatchTouchEvent(ev);
}
if (isContentViewLock) {
isContentViewLock = false;
return super.dispatchTouchEvent(ev);
}
isContentViewLock = false;
direction = 0;
if (move < 0 && move * move > headHeight * headHeight && pullRefresh != null) {
pullRefresh.refresh(true);
((PullListener) headView).pullRefresh();
refreshState = true;
}
if (move > 0 && move * move > footHeight * footHeight && pullRefresh != null) {
pullRefresh.refresh(false);
((PullListener) footView).pullRefresh();
refreshState = true;
}
if (move < 0 && move < -headHeight) {
scrollTo(0, -headHeight);
invalidate();
return true;
}
if (move > 0 && move > footHeight) {
scrollTo(0, footHeight);
invalidate();
return true;
}
refreshState = false;
move = 0;
scrollTo(0, 0);
invalidate();
break;
default:
break;
}
super.dispatchTouchEvent(ev);
return true;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_MOVE:
offetcY = ev.getY() - downY;
offetcX = ev.getX() - downX;
if (direction == 0) {
if (offetcX * offetcX > offetcY * offetcY) {
if (offetcX * offetcX > 25)
direction = 1;
// 横向
} else {
if (offetcY * offetcY > 25)
direction = 2;
// 纵向
}
}
if (direction == 1 || direction == 0) {
scrollTo(0, 0);
return false;
}
if (move < 0 && move < -headHeight) {
return true;
}
if (move > 0 && move > footHeight) {
return true;
}
if (move != 0) {
return true;
}
default:
break;
}
return super.onInterceptTouchEvent(ev);
}
public void refreshSuccess(String success) {
if (headView != null && headView instanceof PullListener) {
((PullListener) headView).pullSuccess(success);
}
if (footView != null && footView instanceof PullListener) {
((PullListener) footView).pullSuccess(success);
}
handler.sendEmptyMessageDelayed(0, 1000);
}
public void refreshFail(String fail) {
if (headView != null && headView instanceof PullListener) {
((PullListener) headView).pullFail(fail);
}
if (footView != null && footView instanceof PullListener) {
((PullListener) footView).pullFail(fail);
}
handler.sendEmptyMessageDelayed(0, 1000);
}
@Override
public boolean handleMessage(Message msg) {
move = 0;
refreshState = false;
scrollTo(0, 0);
invalidate();
return false;
}
}
这个下拉刷新支持LinearLayout,ListView,还可以进行拓展,并且可以根据下拉距离做动画,经过测试感觉良好