/**
  * 根据当前ListView的滚动状态来设定 {@link #ableToPull}
  * 的值,每次都需要在onTouch中第一个执行,这样可以判断出当前应该是滚动ListView,还是应该进行下拉。
  *
  * @param event
  */
 private void setIsAbleToPull(View view, MotionEvent event) {
   boolean oldVal = this.ableToPull;
   this.ableToPull = this.pullableView.isPullable(view, event);
   if (this.ableToPull) {
     if (oldVal == false) {
       yDown = event.getRawY();
     }
   } else if (headerLayoutParams.topMargin != hideHeaderHeight) {
     headerLayoutParams.topMargin = hideHeaderHeight;
     header.setLayoutParams(headerLayoutParams);
   }
   if (pullableView.getView() instanceof ListView) {
     View firstChild = ((ListView) pullableView.getView()).getChildAt(0);
     if (firstChild != null) {
       int firstVisiblePos = ((ListView) pullableView.getView()).getFirstVisiblePosition();
       if (firstVisiblePos == 0 && firstChild.getTop() == 0) {
         if (!ableToPull) {
           yDown = event.getRawY();
         }
         // 如果首个元素的上边缘,距离父布局值为0,就说明ListView滚动到了最顶部,此时应该允许下拉刷新
         ableToPull = true;
       } else {
         if (headerLayoutParams.topMargin != hideHeaderHeight) {
           headerLayoutParams.topMargin = hideHeaderHeight;
           header.setLayoutParams(headerLayoutParams);
         }
         ableToPull = false;
       }
     } else {
       // 如果ListView中没有元素,也应该允许下拉刷新
       ableToPull = true;
     }
   }
 }
 /** 当ListView被触摸时调用,其中处理了各种下拉刷新的具体逻辑。 */
 @Override
 public boolean onTouch(View v, MotionEvent event) {
   setIsAbleToPull(v, event);
   boolean retVal = false;
   if (ableToPull) {
     switch (event.getAction()) {
       case MotionEvent.ACTION_DOWN:
         yDown = event.getRawY();
         // if(log.isDebugEnabled()){
         // log.debug("Touch down, y position :"+yDown);
         // }
         break;
       case MotionEvent.ACTION_MOVE:
         float yMove = event.getRawY();
         int distance = (int) (yMove - yDown);
         // if(log.isDebugEnabled()){
         // log.debug("Touch down and move, y position :"+yMove+", move distance :"+distance);
         // }
         // 如果手指是下滑状态,并且下拉头是完全隐藏的,就屏蔽下拉事件
         if (distance <= 0 && headerLayoutParams.topMargin <= hideHeaderHeight) {
           return false;
         }
         if (distance < touchSlop) {
           return false;
         }
         if (!pullStarted) {
           // if(log.isDebugEnabled()){
           // log.debug("Pull started, touchSlop = "+touchSlop);
           // }
           pullableView.pullStarted(v);
           pullStarted = true;
         }
         retVal = true;
         if (currentStatus != STATUS_REFRESHING) {
           if (headerLayoutParams.topMargin > 0) {
             currentStatus = STATUS_RELEASE_TO_REFRESH;
           } else {
             currentStatus = STATUS_PULL_TO_REFRESH;
           }
           // 通过偏移下拉头的topMargin值,来实现下拉效果
           headerLayoutParams.topMargin = (distance / 2) + hideHeaderHeight;
           header.setLayoutParams(headerLayoutParams);
         }
         break;
       case MotionEvent.ACTION_UP:
       default:
         if (pullStarted) {
           pullableView.pullEnded(v);
           pullStarted = false;
           retVal = true;
         }
         if (currentStatus == STATUS_RELEASE_TO_REFRESH) {
           // 松手时如果是释放立即刷新状态,就去调用正在刷新的任务
           setOnRefreshing(true);
         } else if (currentStatus == STATUS_PULL_TO_REFRESH) {
           // 松手时如果是下拉状态,就去调用隐藏下拉头的任务
           hideHeader();
         }
         break;
     }
     // 时刻记得更新下拉头中的信息
     if (currentStatus == STATUS_PULL_TO_REFRESH || currentStatus == STATUS_RELEASE_TO_REFRESH) {
       updateHeaderView();
       // 当前正处于下拉或释放状态,要让ListView失去焦点,否则被点击的那一项会一直处于选中状态
       pullableView.getView().setPressed(false);
       pullableView.getView().setFocusable(false);
       pullableView.getView().setFocusableInTouchMode(false);
       lastStatus = currentStatus;
       // 当前正处于下拉或释放状态,通过返回true屏蔽掉ListView的滚动事件
     }
   }
   return retVal;
 }