android下拉刷新框架

上次做的那个下拉刷新效果太差了,于是看了一下网上的刷新框架,自己实现了一个类似于百度贴吧的下拉刷新

我暂时发现原始下拉刷新的效果有两种

一种是百度的,down手势的时候,未在顶部,也能够下拉出刷新头部,下拉出头部之后,再继续上拉,头部隐藏之后,手势也会完全的交给内容View,这种在我看来是比较合理的

另一种就是很多软件用的,只有当down手势的那一刻整个内容区域在顶部的时候才可以下拉刷新,并且下拉出头部再上拉隐藏,内容view也获取不到后续的手势

我就是按照百度贴吧的效果做的,其中手势的处理算是很蛋疼的一件事情,效果图


其中里面还有listview,

手势的处理

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            lastY = ev.getY();
            //如果此时正在进行滑动,并且此时的状态不为正在刷新,则直接把动画停止
            if(runnable != null && currentState != RefreshState.REFRESHING){
                runnable.stop();
            }
            break;
        case MotionEvent.ACTION_MOVE:
            //如果向下滑动的距离超过了一定的数值,则父控件直接将该手势截取,用于判断是否应该将下拉刷新的view
            //显示出来 @see #isPullDownEnable
            if(isPullDownEnable() && (ev.getY()-lastY) > viewConfiguration.getScaledTouchSlop()){
                //重置回false
                requestDisallowInterceptTouchEvent(false);
                //代表父控件不能释放改手势了
                canReleaseTouchEvent = false;
            }
            //这个条件用来判断,用户把头部下拉出来一点,但是接着上拉,使得头部隐藏,隐藏之后,所有的手势又得重新交给子控件去处理
            //所以此时必须要满足两个条件,一个是我已经截取了该手势和另一个是我应该释放该手势
            //另一个需要注意的是listview,这个view很特殊
            if(canCatchTouchevent && canReleaseTouchEvent && isChildViewNeedDown()){
                if(first){
                    ev.setAction(MotionEvent.ACTION_DOWN);
                    Log.e("zhao", "listview"+ev.getAction());
                    first = false;
                }
                contentView.dispatchTouchEvent(ev);
            }
            break;
        case MotionEvent.ACTION_UP:
            //不要忘记将其重置回false状态
            canCatchTouchevent = false;
            canReleaseTouchEvent = false;
            first = true;
        default:
            break;
    }
//		Log.e("zhao", "dispatch");
    return super.dispatchTouchEvent(ev);
}

/**
 * 由于listView开始滚动的时候,他会调用parent.requestDisallowInterceptTouchEvent(true);
 * 所以父控件的这个onInterceptTouchEvent以后就不调用了,这个一定要注意,所以这种情况就需要去dispatchTouchEvent中
 * 去处理了,因为dispatchTouchEvent是一定会执行的
 */
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            lastY = ev.getY();
            canCatchTouchevent = false;
            //如果此时头部可见,则一定截取该手势
            if(isHeadVisible())
                canCatchTouchevent = true;
            break;
        case MotionEvent.ACTION_MOVE:
            //如果向下滑动的距离超过了一定的数值,则父控件直接将该手势截取,用于判断是否应该将下拉刷新的view
            //显示出来 @see #isPullDownEnable
            if(isPullDownEnable() && (ev.getY()-lastY) > viewConfiguration.getScaledTouchSlop()){
                canCatchTouchevent = true;
            }
            lastY = ev.getY();
            break;
        default:
            break;
    }
//		Log.e("zhao", "onintercept"+canCatchTouchevent);
    return super.onInterceptTouchEvent(ev) || canCatchTouchevent;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    Boolean isHandled = false;
    if(!canReleaseTouchEvent){
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                isHandled = true;
                break;
            case MotionEvent.ACTION_MOVE:
                moveY = event.getY() - lastY;
                lastY = event.getY();
                //如果手势为向上滑动,或者手势向下并且头部没有完全隐藏,这两种情况将该手势截取
                if(isPullDownEnable() && (moveY > 0 || (moveY<=0 && getScrollY()<0)) ){
                    pullHeadDown(moveY);
                    isHandled = true;
                    //这里需要将其置为true,以防用户反复将头部划出,隐藏,划出,隐藏。。。。
                    first = true;
                    canReleaseTouchEvent = false;
                }else{
//					Log.e("zhao", "canrelease"+canReleaseTouchEvent+"movey"+moveY+"getscrolly"+getScrollY());
                    //只有当此时用户已经手动将头部下拉下来,并且此时刷新状态不等于refresing时才将状态变为done
                    //因为可能出现正在刷新但是刷新未完成,但是用户手动下拉使得头部隐藏,此时不应该直接变为done
                    if(!isHeadVisible() && currentState!=RefreshState.REFRESHING) {
                        changeState(RefreshState.DONE);
                    }
                    canReleaseTouchEvent = true;
                }
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                if(currentState == RefreshState.RELEASETOREFRESH){
                    resetRefreshing();
                    changeState(RefreshState.REFRESHING);
                    isHandled = true;
                }else if (currentState == RefreshState.REFRESHING){
                    //此时如果正在刷新,用户还继续往上拉,则重置位置,其他情况不处理
                    if(getScrollY() < -head.getHeight())
                        resetRefreshing();
                }else{
                    changeState(RefreshState.DONE);
                }

                break;
            default:
                break;
        }
    }
//		Log.e("zhao", "ontouch"+isHandled);
    //如果这里返回false,则这个ontouchevent应该recycle,并且touchevent事件又重新开始循环走oninterceptTouchEvent
    return isHandled;
}


代码戳我下载


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值