@Override
  public boolean onTouch(View view, MotionEvent motionEvent) {
    if (mViewWidth < 2) {
      mViewWidth = mListView.getWidth();
    }

    switch (motionEvent.getActionMasked()) {
      case MotionEvent.ACTION_DOWN:
        {
          if (mPaused) {
            return false;
          }

          if (mSwiping) {
            return true;
          }

          // TODO: ensure this is a finger, and set a flag

          // Find the child view that was touched (perform a hit test)
          Rect rect = new Rect();
          int childCount = mListView.getChildCount();
          int headerCount = mListView.getHeaderViewsCount();
          int footerCount = mListView.getFooterViewsCount();
          int[] listViewCoords = new int[2];
          mListView.getLocationOnScreen(listViewCoords);
          int x = (int) motionEvent.getRawX() - listViewCoords[0];
          int y = (int) motionEvent.getRawY() - listViewCoords[1];
          View child = null;
          for (int i = headerCount; i < (childCount - footerCount); i++) {
            child = mListView.getChildAt(i);
            child.getHitRect(rect);
            if (rect.contains(x, y)) {
              mDownView = child;
              break;
            }
          }

          if (mDownView != null) {

            mDownX = motionEvent.getRawX();
            mDownY = motionEvent.getRawY();
            mDownPosition = mListView.getPositionForView(mDownView);
            if (mDownPosition != ListView.INVALID_POSITION
                && mDownPosition < mListView.getAdapter().getCount()) {
              if (mListView.getAdapter().getItem(mDownPosition) instanceof Card) {
                if (mCallbacks.canDismiss(
                    mDownPosition, (Card) mListView.getAdapter().getItem(mDownPosition))) {
                  mVelocityTracker = VelocityTracker.obtain();
                  mVelocityTracker.addMovement(motionEvent);
                } else {
                  mDownView = null;
                }
              } else {
                mDownView = null;
              }
            } else {
              mDownView = null;
            }
          }
          view.onTouchEvent(motionEvent);
          return true;
          // return false;
        }

      case MotionEvent.ACTION_UP:
        {
          if (mVelocityTracker == null) {
            break;
          }

          float deltaX = motionEvent.getRawX() - mDownX;
          mVelocityTracker.addMovement(motionEvent);
          mVelocityTracker.computeCurrentVelocity(1000);
          float velocityX = mVelocityTracker.getXVelocity();
          float absVelocityX = Math.abs(velocityX);
          float absVelocityY = Math.abs(mVelocityTracker.getYVelocity());
          boolean dismiss = false;
          boolean dismissRight = false;
          if (Math.abs(deltaX) > mViewWidth / swipeDistanceDivisor && mSwiping) {
            dismiss = true;
            dismissRight = deltaX > 0;
          } else if (mMinFlingVelocity <= absVelocityX
              && absVelocityX <= mMaxFlingVelocity
              && absVelocityY < absVelocityX
              && mSwiping) {
            // dismiss only if flinging in the same direction as dragging
            dismiss = (velocityX < 0) == (deltaX < 0);
            dismissRight = mVelocityTracker.getXVelocity() > 0;
          }
          if (dismiss && mDownPosition != ListView.INVALID_POSITION) {
            // dismiss
            dismiss(mDownView, mDownPosition - mListView.getHeaderViewsCount(), dismissRight);

          } else {
            // cancel
            mDownView
                .animate()
                .translationX(0)
                .alpha(1)
                .setDuration(mAnimationTime)
                .setListener(null);
          }

          mVelocityTracker.recycle();
          mVelocityTracker = null;
          mDownX = 0;
          mDownY = 0;
          mDownView = null;
          mDownPosition = ListView.INVALID_POSITION;
          if (mSwiping) {
            // To prevent onClick event with a fast swipe
            mSwiping = false;
            return true;
          }
          mSwiping = false;
          break;
        }

      case MotionEvent.ACTION_CANCEL:
        {
          if (mVelocityTracker == null) {
            break;
          }

          if (mDownView != null) {
            // cancel
            mDownView
                .animate()
                .translationX(0)
                .alpha(1)
                .setDuration(mAnimationTime)
                .setListener(null);
          }
          mVelocityTracker.recycle();
          mVelocityTracker = null;
          mDownX = 0;
          mDownY = 0;
          mDownView = null;
          mDownPosition = ListView.INVALID_POSITION;
          mSwiping = false;
          break;
        }

      case MotionEvent.ACTION_MOVE:
        {
          if (mVelocityTracker == null || mPaused) {
            break;
          }

          mVelocityTracker.addMovement(motionEvent);
          float deltaX = motionEvent.getRawX() - mDownX;
          float deltaY = motionEvent.getRawY() - mDownY;
          boolean movementAllowed = isSwipeMovementAllowed(deltaX);
          if (Math.abs(deltaX) > mSlop
              && Math.abs(deltaY) < Math.abs(deltaX) / 2
              && movementAllowed) {
            mSwiping = true;
            mSwipingSlop = (deltaX > 0 ? mSlop : -mSlop);
            mListView.requestDisallowInterceptTouchEvent(true);

            // Cancel ListView's touch (un-highlighting the item)
            MotionEvent cancelEvent = MotionEvent.obtain(motionEvent);
            cancelEvent.setAction(
                MotionEvent.ACTION_CANCEL
                    | (motionEvent.getActionIndex() << MotionEvent.ACTION_POINTER_INDEX_SHIFT));
            mListView.onTouchEvent(cancelEvent);
            view.onTouchEvent(cancelEvent);
            cancelEvent.recycle();
          }

          if (mSwiping) {
            mDownView.setTranslationX(deltaX - mSwipingSlop);
            mDownView.setAlpha(Math.max(0f, Math.min(1f, 1f - 2f * Math.abs(deltaX) / mViewWidth)));
            return true;
          }
          break;
        }
    }
    return false;
  }
  @Override
  public boolean onTouch(View view, MotionEvent motionEvent) {
    if (mViewWidth < 2) {
      mViewWidth = mListView.getWidth();
    }

    switch (motionEvent.getActionMasked()) {
      case MotionEvent.ACTION_DOWN:
        {
          if (mPaused) {
            return false;
          }

          // TODO: ensure this is a finger, and set a flag

          // Find the child view that was touched (perform a hit test)
          Rect rect = new Rect();
          int childCount = mListView.getChildCount();
          int[] listViewCoords = new int[2];
          mListView.getLocationOnScreen(listViewCoords);
          int x = (int) motionEvent.getRawX() - listViewCoords[0];
          int y = (int) motionEvent.getRawY() - listViewCoords[1];
          View child;
          for (int i = 0; i < childCount; i++) {
            child = mListView.getChildAt(i);
            child.getHitRect(rect);
            if (rect.contains(x, y)) {
              mDownView = child;
              break;
            }
          }

          if (mDownView != null) {
            mDownX = motionEvent.getRawX();
            mDownPosition = mListView.getPositionForView(mDownView);
            if (((ListItem) mListView.getAdapter().getItem(mDownPosition)).getId() < 0) {
              return true;
            }

            mVelocityTracker = VelocityTracker.obtain();
            mVelocityTracker.addMovement(motionEvent);
          }
          view.onTouchEvent(motionEvent);
          return true;
        }

      case MotionEvent.ACTION_UP:
        {
          if (mVelocityTracker == null) {
            break;
          }

          float deltaX = motionEvent.getRawX() - mDownX;
          mVelocityTracker.addMovement(motionEvent);
          mVelocityTracker.computeCurrentVelocity(1000);
          float velocityX = Math.abs(mVelocityTracker.getXVelocity());
          float velocityY = Math.abs(mVelocityTracker.getYVelocity());
          boolean dismiss = false;
          boolean dismissRight = false;
          if (Math.abs(deltaX) > mViewWidth / 2) {
            dismiss = true;
            dismissRight = deltaX > 0;
          } else if (mMinFlingVelocity <= velocityX
              && velocityX <= mMaxFlingVelocity
              && velocityY < velocityX) {
            dismiss = true;
            dismissRight = mVelocityTracker.getXVelocity() > 0;
          }
          if (dismiss) {
            // dismiss
            final View downView = mDownView; // mDownView gets null'd before animation ends
            final int downPosition = mDownPosition;
            ++mDismissAnimationRefCount;
            animate(mDownView)
                .translationX(dismissRight ? mViewWidth : -mViewWidth)
                .alpha(0)
                .setDuration(mAnimationTime)
                .setListener(
                    new AnimatorListenerAdapter() {
                      @Override
                      public void onAnimationEnd(Animator animation) {
                        performDismiss(downView, downPosition);
                      }
                    });
          } else {
            // cancel
            animate(mDownView)
                .translationX(0)
                .alpha(1)
                .setDuration(mAnimationTime)
                .setListener(null);
          }
          mVelocityTracker = null;
          mDownX = 0;
          mDownView = null;
          mDownPosition = ListView.INVALID_POSITION;
          mSwiping = false;
          break;
        }

      case MotionEvent.ACTION_MOVE:
        {
          if (mVelocityTracker == null || mPaused) {
            break;
          }

          mVelocityTracker.addMovement(motionEvent);
          float deltaX = motionEvent.getRawX() - mDownX;
          if (Math.abs(deltaX) > mSlop) {
            mSwiping = true;
            mListView.requestDisallowInterceptTouchEvent(true);

            // Cancel ListView's touch (un-highlighting the item)
            MotionEvent cancelEvent = MotionEvent.obtain(motionEvent);
            cancelEvent.setAction(
                MotionEvent.ACTION_CANCEL
                    | (motionEvent.getActionIndex() << MotionEvent.ACTION_POINTER_INDEX_SHIFT));
            mListView.onTouchEvent(cancelEvent);
          }

          if (mSwiping) {
            setTranslationX(mDownView, deltaX);
            setAlpha(
                mDownView, Math.max(0f, Math.min(1f, 1f - 2f * Math.abs(deltaX) / mViewWidth)));
            return true;
          }
          break;
        }
    }
    return false;
  }
  @Override
  public boolean onTouch(View view, MotionEvent motionEvent) {
    if (mViewWidth < 2) {
      mViewWidth = mListView.getWidth();
    }

    switch (motionEvent.getActionMasked()) {
      case MotionEvent.ACTION_DOWN:
        {
          if (mPaused) {
            return false;
          }

          // TODO: ensure this is a finger, and set a flag

          // Find the child view that was touched (perform a hit test)
          Rect rect = new Rect();
          int childCount = mListView.getChildCount();
          int[] listViewCoords = new int[2];
          mListView.getLocationOnScreen(listViewCoords);
          int x = (int) motionEvent.getRawX() - listViewCoords[0];
          int y = (int) motionEvent.getRawY() - listViewCoords[1];
          View child;
          for (int i = 0; i < childCount; i++) {
            child = mListView.getChildAt(i);
            child.getHitRect(rect);
            if (rect.contains(x, y)) {
              // mDownView = child;

              Log.i("SWIPE", child.getClass().toString());
              if (child instanceof FrameLayout) {
                mDownView = ((FrameLayout) child).getChildAt(1);
                Log.i("SWIPE", String.valueOf(((FrameLayout) child).getChildCount()));
              }
              break;
            }
          }

          if (mDownView != null) {
            mDownX = motionEvent.getRawX();
            mDownY = motionEvent.getRawY();
            lastX = motionEvent.getRawX();
            mDownPosition = mListView.getPositionForView(mDownView);
            if (mCallbacks.canDismiss(mDownPosition)) {
              mVelocityTracker = VelocityTracker.obtain();
              mVelocityTracker.addMovement(motionEvent);
            } else {
              mDownView = null;
            }
          }
          return false;
        }

      case MotionEvent.ACTION_CANCEL:
        {
          if (mVelocityTracker == null) {
            break;
          }

          if (mDownView != null && mSwiping) {
            // cancel
            mDownView
                .animate()
                .translationX(0)
                .alpha(1)
                .setDuration(mAnimationTime)
                .setListener(null);
          }
          mVelocityTracker.recycle();
          mVelocityTracker = null;
          mDownX = 0;
          mDownY = 0;
          mDownView = null;
          mDownPosition = ListView.INVALID_POSITION;
          mSwiping = false;
          break;
        }

      case MotionEvent.ACTION_UP:
        {
          if (mVelocityTracker == null) {
            break;
          }

          float deltaX = motionEvent.getRawX() - mDownX;
          mVelocityTracker.addMovement(motionEvent);
          mVelocityTracker.computeCurrentVelocity(1000);
          float velocityX = mVelocityTracker.getXVelocity();
          float absVelocityX = Math.abs(velocityX);
          float absVelocityY = Math.abs(mVelocityTracker.getYVelocity());
          boolean dismiss = false;
          boolean dismissRight = false;
          if (Math.abs(deltaX) > mViewWidth / 2 && mSwiping) {
            dismiss = true;
            dismissRight = deltaX > 0;
          } else if (mMinFlingVelocity <= absVelocityX
              && absVelocityX <= mMaxFlingVelocity
              && absVelocityY < absVelocityX
              && mSwiping) {
            // dismiss only if flinging in the same direction as dragging
            dismiss = (velocityX < 0) == (deltaX < 0);
            dismissRight = mVelocityTracker.getXVelocity() > 0;
          }
          if (dismiss && mDownPosition != ListView.INVALID_POSITION) {
            // dismiss
            final View downView = mDownView; // mDownView gets null'd before animation ends
            final int downPosition = mDownPosition;
            ++mDismissAnimationRefCount;
            mDownView
                .animate()
                .translationX(dismissRight ? mViewWidth - 1 : -mViewWidth + 1)
                // .alpha(0)
                .setDuration(mAnimationTime)
                .setListener(
                    new AnimatorListenerAdapter() {
                      @Override
                      public void onAnimationEnd(Animator animation) {
                        performDismiss(downView, downPosition);
                      }
                    });
          } else {
            // cancel
            mDownView
                .animate()
                .translationX(0)
                .alpha(1)
                .setDuration(mAnimationTime)
                .setListener(null);
          }
          mVelocityTracker.recycle();
          mVelocityTracker = null;
          mDownX = 0;
          mDownY = 0;
          mDownView = null;
          mDownPosition = ListView.INVALID_POSITION;
          mSwiping = false;
          break;
        }

      case MotionEvent.ACTION_MOVE:
        {
          if (mVelocityTracker == null || mPaused) {
            break;
          }

          mVelocityTracker.addMovement(motionEvent);
          float deltaX = motionEvent.getRawX() - mDownX;
          float deltaY = motionEvent.getRawY() - mDownY;

          if (motionEvent.getRawX() - lastX > 0) {
            mCallbacks.swipeToRight();
          } else {
            mCallbacks.swipeToLeft();
          }
          lastX = motionEvent.getRawX();

          if (Math.abs(deltaX) > mSlop && Math.abs(deltaY) < Math.abs(deltaX) / 2) {
            mSwiping = true;
            mSwipingSlop = (deltaX > 0 ? mSlop : -mSlop);
            mListView.requestDisallowInterceptTouchEvent(true);

            // Cancel ListView's touch (un-highlighting the item)
            MotionEvent cancelEvent = MotionEvent.obtain(motionEvent);
            cancelEvent.setAction(
                MotionEvent.ACTION_CANCEL
                    | (motionEvent.getActionIndex() << MotionEvent.ACTION_POINTER_INDEX_SHIFT));
            mListView.onTouchEvent(cancelEvent);
            cancelEvent.recycle();
          }

          if (mSwiping) {
            mDownView.setTranslationX(deltaX - mSwipingSlop);
            // mDownView.setAlpha(Math.max(0f, Math.min(1f,
            //        1f - 2f * Math.abs(deltaX) / mViewWidth)));
            return true;
          }
          break;
        }
    }
    return false;
  }
Exemplo n.º 4
0
  @SuppressLint("ResourceAsColor")
  @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
  @Override
  public boolean onTouch(final View view, MotionEvent event) {
    if (mViewWidth < 2) {
      mViewWidth = mListView.getWidth();
      smallWidth = mViewWidth / 7;
      textwidth2 = mViewWidth / 3;
      textwidth = textwidth2;
      //            原版
      //            largewidth	=	textwidth+textwidth2;
      //           自己修改
      largewidth = textwidth;
    }

    int tempwidth = 0;
    if (SwipeType == 1) tempwidth = smallWidth;
    else tempwidth = textwidth2 / 2;

    switch (event.getActionMasked()) {
      case MotionEvent.ACTION_DOWN:
        {
          if (mPaused) {
            return false;
          }
          Rect rect = new Rect();
          int childCount = mListView.getChildCount();
          int[] listViewCoords = new int[2];
          mListView.getLocationOnScreen(listViewCoords);
          int x = (int) event.getRawX() - listViewCoords[0];
          int y = (int) event.getRawY() - listViewCoords[1];
          ViewGroup child;
          for (int i = 0; i < childCount; i++) {
            child = (ViewGroup) mListView.getChildAt(i);
            child.getHitRect(rect);
            if (rect.contains(x, y)) {
              mDownView_parent = child;
              mDownView = (ViewGroup) child.findViewById(R.id.list_display_view_container);
              if (mDownView_parent.getChildCount() == 1) {
                textheight = mDownView_parent.getHeight();
                if (SwipeType == Dismiss) {
                  HalfColor = singleColor;
                  //                                HalfDrawable	=
                  //	activity.getResources().getDrawable(R.drawable.content_discard);
                }
                SetBackGroundforList();
              }

              if (old_mDownView != null && mDownView != old_mDownView) {
                ResetListItem(old_mDownView);
                old_mDownView = null;
                return false;
              }
              break;
            }
          }

          if (mDownView != null) {
            mDownX = event.getRawX();
            mDownY = event.getRawY();
            mDownPosition = mListView.getPositionForView(mDownView);
            mVelocityTracker = VelocityTracker.obtain();
            mVelocityTracker.addMovement(event);
          } else {
            mDownView = null;
          }

          // mSwipeDetected              =   false;
          temp_position = mListView.pointToPosition((int) event.getX(), (int) event.getY());
          view.onTouchEvent(event);
          return true;
        }

      case MotionEvent.ACTION_UP:
        {
          if (mVelocityTracker == null) {
            break;
          }
          float deltaX = event.getRawX() - mDownX;
          // 在OnItemClick事件中判断如果Deltax!=0则表示不是点击事件
          DeltaX = deltaX;
          mVelocityTracker.addMovement(event);
          mVelocityTracker.computeCurrentVelocity(1000); // 1000 by defaut but
          float velocityX = mVelocityTracker.getXVelocity(); // it was too much
          float absVelocityX = Math.abs(velocityX);
          float absVelocityY = Math.abs(mVelocityTracker.getYVelocity());
          boolean swipe = false;
          boolean swipeRight = false;

          if (Math.abs(deltaX) > tempwidth) {
            swipe = true;
            swipeRight = deltaX > 0;

          } else if (mMinFlingVelocity <= absVelocityX
              && absVelocityX <= mMaxFlingVelocity
              && absVelocityY < absVelocityX) {
            // dismiss only if flinging in the same direction as dragging
            swipe = (velocityX < 0) == (deltaX < 0);
            swipeRight = mVelocityTracker.getXVelocity() > 0;
          }
          if (deltaX < 0 && swipe) {
            mListView.setDrawSelectorOnTop(false);
            // && Math.abs(DeltaY)<30
            if (swipe && !swipeRight && deltaX <= -tempwidth && Math.abs(DeltaY) < 100) {
              FullSwipeTrigger();
            } else if (deltaX >= -textwidth && SwipeType == Double) {
              ResetListItem(mDownView);
            } else {
              ResetListItem(mDownView);
            }
          } else if (deltaX != 0) {
            ResetListItem(mDownView);
          }

          mVelocityTracker.recycle();
          mVelocityTracker = null;
          mDownX = 0;
          mDownView = null;
          mDownPosition = ListView.INVALID_POSITION;
          mSwiping = false;
          break;
        }

        // 根据手势滑动方向滑出滑入

      case MotionEvent.ACTION_MOVE:
        {
          float deltaX = event.getRawX() - mDownX;
          float deltaY = event.getRawY() - mDownY;
          DeltaY = deltaY;
          if (mVelocityTracker == null || mPaused || deltaX > 0) {
            break;
          }

          mVelocityTracker.addMovement(event);

          // && Math.abs(deltaY)<30
          if (Math.abs(deltaX) > (mSlop * 5) && Math.abs(deltaY) < 50) {
            mSwiping = true;
            mListView.requestDisallowInterceptTouchEvent(true);

            // Cancel ListView's touch (un-highlighting the item)
            MotionEvent cancelEvent = MotionEvent.obtain(event);
            cancelEvent.setAction(
                MotionEvent.ACTION_CANCEL
                    | (event.getActionIndex() << MotionEvent.ACTION_POINTER_INDEX_SHIFT));
            mListView.onTouchEvent(cancelEvent);
            cancelEvent.recycle();
          } else if (Math.abs(deltaY) > 50) {
            mSwiping = false;
            //                     ResetListItem(mDownView);
          }
          System.out.println(
              "<<<<<<<<<" + deltaY + "<<<<<<" + deltaX + "<<<<" + mSwiping + "<<<<<" + mSlop * 10);
          if (mSwiping && deltaX < 0) {
            int width;
            //                     if(SwipeType==1){
            width = textwidth2;
            //                     }
            //                     else{
            //                         width	=	largewidth;
            //                     }

            if (-deltaX < width) {

              mDownView.setTranslationX(deltaX);
              return false;
            }
            return false;
          } else if (mSwiping) {
            ResetListItem(mDownView);
          }
          break;
        }
    }
    return false;
  }
  @Override
  public boolean onTouch(View view, MotionEvent motionEvent) {
    if (mViewWidth < 2) {
      mViewWidth = mListView.getWidth();
    }

    switch (motionEvent.getActionMasked()) {
      case MotionEvent.ACTION_DOWN:
        {
          if (mPaused) {
            return false;
          }

          // TODO: ensure this is a finger, and set a flag

          // Find the child view that was touched (perform a hit test)
          Rect rect = new Rect();
          int childCount = mListView.getChildCount();
          int[] listViewCoords = new int[2];
          mListView.getLocationOnScreen(listViewCoords);
          int x = (int) motionEvent.getRawX() - listViewCoords[0];
          int y = (int) motionEvent.getRawY() - listViewCoords[1];
          View child;
          for (int i = 0; i < childCount; i++) {
            child = mListView.getChildAt(i);
            child.getHitRect(rect);
            if (rect.contains(x, y)) {
              try {
                mDownViewGroup = (SwipeViewGroup) child;
                mDownView = mFixedBackgrounds ? mDownViewGroup.getContentView() : child;
                if (!mFixedBackgrounds) mDownViewGroup.translateBackgrounds();
              } catch (Exception e) {
                mDownView = child;
              }
              break;
            }
          }

          if (mDownView != null) {
            mDownX = motionEvent.getRawX();
            mDownY = motionEvent.getRawY();
            mDownPosition = mListView.getPositionForView(mDownView);
            if (mCallbacks.hasActions(mDownPosition)) {
              mVelocityTracker = VelocityTracker.obtain();
              mVelocityTracker.addMovement(motionEvent);
            } else {
              mDownView = null;
            }
          }
          return false;
        }

      case MotionEvent.ACTION_CANCEL:
        {
          if (mVelocityTracker == null) {
            break;
          }

          if (mDownView != null && mSwiping) {
            // cancel
            mDownView
                .animate()
                .translationX(0)
                .alpha(1)
                .setDuration(mAnimationTime)
                .setListener(
                    new AnimatorListenerAdapter() {
                      @Override
                      public void onAnimationEnd(Animator animation) {
                        mDownViewGroup.showBackground(SwipeDirections.DIRECTION_NEUTRAL, false);
                      }
                    });
          }
          mVelocityTracker.recycle();
          mVelocityTracker = null;
          mDownX = 0;
          mDownY = 0;
          mDownView = null;
          mDownPosition = ListView.INVALID_POSITION;
          mSwiping = false;
          mDirection = SwipeDirections.DIRECTION_NEUTRAL;
          mFar = false;
          break;
        }

      case MotionEvent.ACTION_UP:
        {
          if (mVelocityTracker == null) {
            break;
          }

          float deltaX = motionEvent.getRawX() - mDownX;
          mVelocityTracker.addMovement(motionEvent);
          mVelocityTracker.computeCurrentVelocity(1000);
          float velocityX = mVelocityTracker.getXVelocity();
          float absVelocityX = Math.abs(velocityX);
          float absVelocityY = Math.abs(mVelocityTracker.getYVelocity());
          boolean dismiss = false;
          boolean dismissRight = false;
          if (Math.abs(deltaX) > (mViewWidth * mNormalSwipeFraction) && mSwiping) {
            dismiss = true;
            dismissRight = deltaX > 0;
          } else if (mMinFlingVelocity <= absVelocityX
              && absVelocityX <= mMaxFlingVelocity
              && absVelocityY < absVelocityX
              && mSwiping) {
            // dismiss only if flinging in the same direction as dragging
            dismiss = (velocityX < 0) == (deltaX < 0);
            dismissRight = mVelocityTracker.getXVelocity() > 0;
          }
          if (dismiss && mDownPosition != ListView.INVALID_POSITION) {
            // dismiss
            final View downView = mDownView; // mDownView gets null'd before animation ends
            final int downPosition = mDownPosition;
            final int direction = mDirection;
            ++mDismissAnimationRefCount;
            mDownView
                .animate()
                .translationX(dismissRight ? mViewWidth : -mViewWidth)
                .alpha(mFadeOut ? 0 : 1)
                .setDuration(mAnimationTime)
                .setListener(
                    new AnimatorListenerAdapter() {
                      @Override
                      public void onAnimationEnd(Animator animation) {
                        boolean performDismiss =
                            mCallbacks.onPreAction(mListView, downPosition, direction);
                        if (performDismiss) performDismiss(downView, downPosition, direction);
                        else slideBack(downView, downPosition, direction);
                      }
                    });
          } else {
            // cancel
            mDownView
                .animate()
                .translationX(0)
                .alpha(1)
                .setDuration(mAnimationTime)
                .setListener(
                    new AnimatorListenerAdapter() {
                      @Override
                      public void onAnimationEnd(Animator animation) {
                        mDownViewGroup.showBackground(SwipeDirections.DIRECTION_NEUTRAL, false);
                      }
                    });
          }
          mVelocityTracker.recycle();
          mVelocityTracker = null;
          mDownX = 0;
          mDownY = 0;
          mDownView = null;
          mDownPosition = ListView.INVALID_POSITION;
          mSwiping = false;
          mDirection = SwipeDirections.DIRECTION_NEUTRAL;
          mFar = false;
          break;
        }

      case MotionEvent.ACTION_MOVE:
        {
          if (mVelocityTracker == null || mPaused) {
            break;
          }

          mVelocityTracker.addMovement(motionEvent);
          float deltaX = motionEvent.getRawX() - mDownX;
          float deltaY = motionEvent.getRawY() - mDownY;
          if (!mSwiping && Math.abs(deltaX) > mSlop && Math.abs(deltaY) < Math.abs(deltaX) / 2) {
            mSwiping = true;
            mSwipingSlop = (deltaX > 0 ? mSlop : -mSlop);

            mListView.requestDisallowInterceptTouchEvent(true);

            // Cancel ListView's touch (un-highlighting the item)
            MotionEvent cancelEvent = MotionEvent.obtain(motionEvent);
            cancelEvent.setAction(
                MotionEvent.ACTION_CANCEL
                    | (motionEvent.getActionIndex() << MotionEvent.ACTION_POINTER_INDEX_SHIFT));
            mListView.onTouchEvent(cancelEvent);
            cancelEvent.recycle();
          }

          if (mSwiping) {
            if (mDirection * deltaX < 0) mFar = false;
            if (!mFar && Math.abs(deltaX) > mViewWidth * mFarSwipeFraction) mFar = true;
            if (!mFar)
              mDirection =
                  (deltaX > 0
                      ? SwipeDirections.DIRECTION_NORMAL_RIGHT
                      : SwipeDirections.DIRECTION_NORMAL_LEFT);
            else
              mDirection =
                  (deltaX > 0
                      ? SwipeDirections.DIRECTION_FAR_RIGHT
                      : SwipeDirections.DIRECTION_FAR_LEFT);
            mDownViewGroup.showBackground(
                mDirection,
                mDimBackgrounds && (Math.abs(deltaX) < mViewWidth * mNormalSwipeFraction));

            mDownView.setTranslationX(deltaX - mSwipingSlop);
            if (mFadeOut)
              mDownView.setAlpha(
                  Math.max(0f, Math.min(1f, 1f - 2f * Math.abs(deltaX) / mViewWidth)));
            return true;
          }
          break;
        }
    }
    return false;
  }