您的位置:首页 > 其它

下拉刷新的ScrollView 不影响item点击事件

2016-12-23 16:08 183 查看
ScrollView 的item有了点击事件后,按item下拉时ScrollView 已经失去了事件 下面是个人做的处理方式,KiciScrollView 附demo下载

注:支持API11及以上

注:使用时子View不能设置onClick事件 在setChildOnClick(); 里处理, 默认按下小于150毫秒 并且在一定移动距离内视为单击

主类

public class KiciScrollView extends ScrollView {

public KiciScrollView(Context context) {
this(context, null);
}

public KiciScrollView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public KiciScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}

private int protoY; //原始位置
private float downY;// 按下位置
private long time; // 记录按下时间
private ValueAnimator mAnimator; //回弹动画
private boolean isMove = false;
private boolean isFirst = false;
private boolean isFirstItem;
private View mOnClickView;
private ChildOnClick mChildOnClick; //item 的点击事件
private OnPullDownRefresh mOnPullDownRefresh;//下拉刷新

public void setRefreshStateListener(RefreshStateListener refreshStateListener) {
mRefreshStateListener = refreshStateListener;
}

private RefreshStateListener mRefreshStateListener; //下拉刷新监听

public void setStartRefreshListener(RefreshStartListener refreshStartListener) {
mRefreshStartListener = refreshStartListener;
}

private RefreshStartListener mRefreshStartListener; //下拉刷新 监听开始刷新
/**
* 下拉的状态 0默认 1下拉中 2松开刷新 3加载中
*/
private int type = 0; //
private float refreshHeight = 60; //刷新的位置高度
private View mHeadView;//下载刷新头部
private int topMargin;

private void init() {
setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {

if (protoY <= 10) {
protoY = getMeasuredHeight();
}

switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (mRefreshStateListener != null && type != 3)
mRefreshStateListener.onPulling(0); //初始化
downY = event.getY();
isFirst = true;
if (mAnimator != null) {
mAnimator.cancel();
}
time = System.currentTimeMillis();
break;
case MotionEvent.ACTION_MOVE:
int d = (int) (event.getY() - downY);
if (isFirst && (getScrollY() == 0)) {
isFirst = !isFirst;
if (d < 0) {
break; //首次进来是上拉 不执行
} else {
isMove = true;
}
}
if (d != 0 && isMove) {
setParamsTop(d);
if (mHeadView != null && type != 3) {  // 下拉刷新

float ratio = (event.getY() - downY) / 3 / (dip2px(getContext(), refreshHeight));
if (ratio < 1) {
type = 1;
if (mRefreshStateListener != null)
mRefreshStateListener.onPulling(ratio); //没到刷新条件
} else {//松开刷新
type = 2;
if (mRefreshStateListener != null)
mRefreshStateListener.onMoreThanRefresh();//达到刷新条件
}
}
return true;
}
break;
case MotionEvent.ACTION_UP:
if (isMove) {
if (mHeadView != null && (type == 2 || type == 3)) {//开始刷新
if (type == 2) {
if (mRefreshStateListener != null)
mRefreshStateListener.onRehresh();
if (mRefreshStartListener != null)
mRefreshStartListener.onRefreshStart();
type = 3;
}

marginValueAnimator(dip2px(getContext(), refreshHeight));
} else {
marginValueAnimator(dip2px(getContext(), 0));
}
}
isMove = false;
if (System.currentTimeMillis() - time < 150 && mChildOnClick != null && mOnClickView != null &&
Math.abs((event.getY() - downY)) < dip2px(getContext(), 10f)) { //视为点击事件
mChildOnClick.onChildClick(mOnClickView);
}
break;

}
return false;
}
}
);
}

@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
initListener();
}

/**
* 刷新成功
*/

public void setRefreshSucceed() {
type = 0;
if (mHeadView != null && mRefreshStateListener != null) {
mRefreshStateListener.onRefreshComplete();//
}
marginValueAnimator(0);
}

/**
* 刷新失败
*/

public void setRefreshFailure() {
type = 0;
if (mHeadView != null && mRefreshStateListener != null) {
mRefreshStateListener.onRefreshFailure();//开始刷新
}
marginValueAnimator(0);

}

public void initListener() {//设置子View的事件
try {
ViewGroup viewGroup = (ViewGroup) getChildAt(0);
initListener(viewGroup);
} catch (Exception e) {
e.printStackTrace();
}

}

private void initListener(ViewGroup viewGroup) {
try {
int count = viewGroup.getChildCount();
for (int i = 0; i < count; i++) {
View v = viewGroup.getChildAt(i);
if (v != null)
v.setOnTouchListener(mOnTouchListener);
try {
initListener((ViewGroup) v);
} catch (Exception e) {
}

}
} catch (Exception e) {
e.printStackTrace();
}
}

@Override
public void addView(View child, int width, int height) {
super.addView(child, width, height);
}

/**
* 设置下拉刷新的位置高度  默认高度是60dip
*
* @param height 单位dip
*/
public void setRefreshHeighe(float height) {
refreshHeight = height;
}

/**
* 使用ValueAnimator改变margin的值
*
* @param height 回弹距离
*/
public void marginValueAnimator(final int height) {
//1.调用ofInt(int...values)方法创建ValueAnimator对象
topMargin = height;
mAnimator = ObjectAnimator.ofFloat(0.0F, 1.0F).setDuration(500);
//2.为目标对象的属性变化设置监听器
mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override
public void onAnimationUpdate(ValueAnimator animation) {
// 3.为目标对象的属性设置计算好的属性值
float animatorValue = (float) animation.getAnimatedValue();
MarginLayoutParams marginLayoutParams = (MarginLayoutParams) getLayoutParams();
if (marginLayoutParams.topMargin > height) {
marginLayoutParams.topMargin = (int) (marginLayoutParams.topMargin - marginLayoutParams.topMargin * animatorValue);
} else {
marginLayoutParams.topMargin = (int) (marginLayoutParams.topMargin + (height - marginLayoutParams.topMargin) * animatorValue);
}
setLayoutParams(marginLayoutParams);

if (mHeadView != null) {
ViewGroup.LayoutParams params = mHeadView.getLayoutParams();
if (params.height > height) {
params.height = (int) (params.height - params.height * animatorValue);
} else {
params.height = (int) (params.height + (height - params.height) * animatorValue);
}
mHeadView.setLayoutParams(params);
}
}
});
//4.设置动画的持续时间、是否重复及重复次数等属性
mAnimator.start();
}

/**
* 下拉了距离 更新UI
*
* @param height
*/
private void setParamsTop(int height) {
if (height == 0) return;
MarginLayoutParams marginLayoutParams = (MarginLayoutParams) getLayoutParams();
height = (height / 3) + topMargin;

marginLayoutParams.topMargin = height;
if (mHeadView != null) {
ViewGroup.LayoutParams params = mHeadView.getLayoutParams();
params.height = height;
mHeadView.setLayoutParams(params);
}
setLayoutParams(marginLayoutParams);
}

/**
* 设置item的点击事件
*
* @param childOnClick
*/
public void setChildOnClick(ChildOnClick childOnClick) {
mChildOnClick = childOnClick;
}

/**
* 设置下拉刷新事件
*/
public void setOnPullDownRefresh(OnPullDownRefresh pullDownRefresh) {
mOnPullDownRefresh = pullDownRefresh;
}

/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
*/
public int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}

private OnTouchListener mOnTouchListener = new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
mOnClickView = v;
return false;
}
};

public interface ChildOnClick {
void onChildClick(View view);
}

public interface OnPullDownRefresh {
void onPullDownRefresh();
}

public void setHeadView(View headView) {
mHeadView = headView;
}

/**
* 延时操作
*
* @param activity
* @param runnable
* @param time
*/
public void runOnUIThread(final Activity activity, final Runnable runnable, final int time) {
new Thread() {
@Override
public void run() {
try {
sleep(time);
if (activity != null)
activity.runOnUiThread(runnable);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();

}
}


下面是可自定义的刷新View 在RefreshStateListener 里监听改变状态就好了

public class KiciHeadView extends LinearLayout implements RefreshStateListener {

public KiciHeadView(Context context) {
this(context, null);
}

public KiciHeadView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public KiciHeadView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}

private View mView;
private Animation an;

private void initView() {
mView = View.inflate(getContext(), R.layout.kici_view_headview, this);
mView1 = findViewById(R.id.view1);
mView2 = (TextView) findViewById(R.id.view2);
}

private View mView1; //tup
private TextView mView2;

@Override
public void onPulling(float y) {
mView1.setBackgroundResource(R.drawable.progress_round);
mView1.setRotation(360 * y);
mView2.setText("下拉刷新");
}

@Override
public void onMoreThanRefresh() {

mView1.setRotation(360);
mView2.setText("松开刷新");
}

@Override
public void onRehresh() {
if (an == null) {
an = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
an.setInterpolator(new LinearInterpolator());//不停顿
an.setRepeatCount(-1);//重复次数
an.setFillAfter(true);//停在最后
an.setDuration(1500);
mView1.setAnimation(an);
}
//动画开始
an.start();
mView2.setText("正在刷新...");
}

@Override
public void onRefreshComplete() {
if (an == null)
return;
mView2.setText("刷新成功");
an.cancel();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
mView1.setBackground(null);
} else {
mView1.setBackgroundDrawable(null);
}
}

@Override
public void onRefreshFailure() {
if (an == null)
return;
mView2.setText("刷新失败");
an.cancel();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
mView1.setBackground(null);
} else {
mView1.setBackgroundDrawable(null);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: