android 实现有阻尼下拉/上拉刷新列表

        在上一篇文章《有阻尼下拉刷新列表的实现》中,我解析了如何基于重载dispatchDraw方法重画子View和重载onTouchEvent方法监控受试来实现下拉刷新列表,而在这篇文章中,我将会基于上一篇文章介绍的技术,在下拉刷新列表PullToRefreshListVIew的基础上,加上有阻尼上拉刷新功能。上一篇文章《有阻尼下拉刷新列表的实现》的链接如下。

http://blog.csdn.net/ivan_zgj/article/details/50664780

        好,我们还是先来看看效果。


1. 通过onScrollListener监控listVIew是否滚动到底部

        在PullToRefreshListView中,我们通过onScrollListener回调来监控PullToRefreshListView是否已经滚动到顶部,当时的代码是这样的:

    setOnScrollListener(new OnScrollListener() {  
        @Override  
        public void onScrollStateChanged(AbsListView view, int scrollState) {  
      
        }  
      
        @Override  
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {  
            // 没有子view的时候(没有数据,或者被拉到看不到子view),意味着该listView滚动到顶部  
            if (getChildCount() == 0) {  
                isTop = true;  
                return;  
            }  
            if (firstVisibleItem == 0) {  
                View firstView = getChildAt(0);  
                if (firstView.getTop() + distanceY >= 0) {  
                    // 第一个view可见且其相对parent(该listView)的顶部距离大于等于0,意味着该listView也是滚动到顶部  
                    isTop = true;  
                    return;  
                }  
            }  
            isTop = false;  
        }  
    });    
         当时我们通过判断firstVisibleItem==0以及第一个子View是否完全可见,从而确定PullToRefreshListView是否滚动到顶部。现在,我们加入以下代码来判断PullToRefreshListView是否滚动到底部。

                if (firstVisibleItem + visibleItemCount == totalItemCount) {
                    View firstView = getChildAt(visibleItemCount - 1);
                    if (firstView.getBottom() + distanceY <= getHeight()) {
                        // 最后一个view可见且其相对parent(该listView)的底部距离小于等于listView高度,意味着该listView也是滚动到底部
                        isBottom = true;
                        return;
                    }
                }
                isBottom = false;
        在onScroll方法中,fisrstVisibleItem是指列表当前可见的第一个子View在其adapter中的position,而visibleItemCount是指可见的子View的个数,totalItemCount是指adapter总共有多少个View。因此,我们可以很容易得出结论,当:
firstVisibleItem + visibleItemCount == totalItemCount
成立时,PullToRefreshListView就已经滚动到底部了。


2. 监控滑动手势使listView进入上拉状态

        在PullToRefreshListView中,我们通过重载onTouchEvent方法来监控用户手势,从而判断PullToRefreshListView是否要进行下拉,当时的代码是这样的:

@Override  
public boolean onTouchEvent(MotionEvent ev) {  
    if (lastAction == -1 && ev.getActionMasked() == MotionEvent.ACTION_DOWN) {  
        // 按下的时候  
        lastAction = MotionEvent.ACTION_DOWN;  
        cancelAnimating();  
        L.d(TAG, "touch down");  
    } else if (lastAction == MotionEvent.ACTION_MOVE && ev.getActionMasked() == MotionEvent.ACTION_UP) {  
        // 放开手指,开始回滚  
        isPulling = false;  
        lastAction = -1;  
        startAnimating();  
        L.d(TAG, "touch up");  
    } else if (lastAction == MotionEvent.ACTION_DOWN) {  
        if (ev.getActionMasked() == MotionEvent.ACTION_MOVE) {  
            // 在按下手指的基础上,开始滑动  
            if (isTop && !isPulling) {  
                // listView在顶部而且不处于下拉刷新状态,开始下拉  
                pullStartY = ev.getY();  
                lastAction = MotionEvent.ACTION_MOVE;  
                isPulling = true;  
            }  
        }  
    } else if (lastAction == MotionEvent.ACTION_MOVE) {  
        if (isTop) {  
            // 下拉  
            distanceY = ev.getY() - pullStartY;  
            L.d(TAG, distanceY + "");  
            if (distanceY > 0) {  
                distanceY = (float) (Math.exp(-ev.getY() / pullStartY / 40) * distanceY);  
                // 在下拉状态时取消系统对move动作的响应,完全由本类响应  
                ev.setAction(MotionEvent.ACTION_DOWN);  
            } else {  
                distanceY = 0;  
                // 在下拉过程中往上拉动该listView使得其回到顶部位置,则将该move动作交由系统进行响应  
                ev.setAction(MotionEvent.ACTION_MOVE);  
            }  
        } else {  
            // 在下拉过程中往上拉动listView使listView往下滚动到其没有滚动到顶部,则取消其下拉状态,回到手指按下的初始状态  
            lastAction = MotionEvent.ACTION_DOWN;  
            isPulling = false;  
            distanceY = 0;  
        }  
    }  
    return super.onTouchEvent(ev);  
} 

         现在,我们只需要在lastAction == MotionEvent.ACTION_MOVE判断里面࿰
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值