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

来源:互联网 发布:js如何获取单选框的值 编辑:程序博客网 时间:2024/06/08 12:53

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);        }    }}

0 0
原创粉丝点击