예제 #1
0
  /**
   * @param view The view to be dismissed
   * @param velocity The desired pixels/second speed at which the view should move
   */
  private void dismissChild(final SwipeableItemView view, float velocity) {
    final View animView = mCurrView.getSwipeableView().getView();
    final boolean canAnimViewBeDismissed = mCallback.canChildBeDismissed(view);
    float newPos = determinePos(animView, velocity);
    int duration = determineDuration(animView, newPos, velocity);

    Utils.enableHardwareLayer(animView);
    ObjectAnimator anim = createDismissAnimation(animView, newPos, duration);
    anim.addListener(
        new AnimatorListenerAdapter() {
          @Override
          public void onAnimationEnd(Animator animation) {
            mCallback.onChildDismissed(mCurrView);
            animView.setLayerType(View.LAYER_TYPE_NONE, null);
          }
        });
    anim.addUpdateListener(
        new AnimatorUpdateListener() {
          @Override
          public void onAnimationUpdate(ValueAnimator animation) {
            if (FADE_OUT_DURING_SWIPE && canAnimViewBeDismissed) {
              animView.setAlpha(getAlphaForOffset(animView));
            }
            invalidateGlobalRegion(animView);
          }
        });
    anim.start();
  }
예제 #2
0
  public void snapChild(final SwipeableItemView view) {
    final View animView = view.getSwipeableView().getView();
    final boolean canAnimViewBeDismissed = mCallback.canChildBeDismissed(view);
    final ObjectAnimator anim = createTranslationAnimation(animView, 0);
    final int duration = SNAP_ANIM_LEN;
    anim.setDuration(duration);
    anim.addUpdateListener(
        new AnimatorUpdateListener() {
          @Override
          public void onAnimationUpdate(ValueAnimator animation) {
            if (FADE_OUT_DURING_SWIPE && canAnimViewBeDismissed) {
              animView.setAlpha(getAlphaForOffset(animView));
            }
            invalidateGlobalRegion(animView);
          }
        });
    anim.addListener(
        new Animator.AnimatorListener() {
          @Override
          public void onAnimationStart(Animator animation) {}

          @Override
          public void onAnimationEnd(Animator animation) {
            animView.setAlpha(1.0f);
            mCallback.onDragCancelled(mCurrView);
          }

          @Override
          public void onAnimationCancel(Animator animation) {}

          @Override
          public void onAnimationRepeat(Animator animation) {}
        });
    anim.start();
  }
예제 #3
0
  public boolean onTouchEvent(MotionEvent ev) {
    if (!mDragging) {
      return false;
    }
    mVelocityTracker.addMovement(ev);
    final int action = ev.getAction();
    switch (action) {
      case MotionEvent.ACTION_OUTSIDE:
      case MotionEvent.ACTION_MOVE:
        if (mCurrView != null) {
          float deltaX = ev.getX() - mInitialTouchPosX;
          // If the swipe started in the dead region, ignore it.
          if (mInitialTouchPosX <= (DEAD_REGION_FOR_SWIPE * mDensityScale)) {
            return true;
          }
          // If the user has gone vertical and not gone horizontalish AT
          // LEAST minBeforeLock, switch to scroll. Otherwise, cancel
          // the swipe.
          float minDistance = MIN_SWIPE;
          if (Math.abs(deltaX) < minDistance) {
            // Don't start the drag until at least X distance has
            // occurred.
            return true;
          }
          // don't let items that can't be dismissed be dragged more
          // than maxScrollDistance
          if (CONSTRAIN_SWIPE && !mCallback.canChildBeDismissed(mCurrView)) {
            float size = getSize(mCurrAnimView);
            float maxScrollDistance = 0.15f * size;
            if (Math.abs(deltaX) >= size) {
              deltaX = deltaX > 0 ? maxScrollDistance : -maxScrollDistance;
            } else {
              deltaX = maxScrollDistance * (float) Math.sin((deltaX / size) * (Math.PI / 2));
            }
          }
          setTranslation(mCurrAnimView, deltaX);
          if (FADE_OUT_DURING_SWIPE && mCanCurrViewBeDimissed) {
            mCurrAnimView.setAlpha(getAlphaForOffset(mCurrAnimView));
            if (mPrevView != null) {
              // Base how much the text of the prev item is faded
              // on how far the current item has moved.
              mPrevView.setTextAlpha(getTextAlphaForOffset(mCurrAnimView));
            }
          }
          invalidateGlobalRegion(mCurrView.getSwipeableView().getView());
        }
        break;
      case MotionEvent.ACTION_UP:
      case MotionEvent.ACTION_CANCEL:
        if (mCurrView != null) {
          float maxVelocity = MAX_DISMISS_VELOCITY * mDensityScale;
          mVelocityTracker.computeCurrentVelocity(1000 /* px/sec */, maxVelocity);
          float escapeVelocity = SWIPE_ESCAPE_VELOCITY * mDensityScale;
          float velocity = getVelocity(mVelocityTracker);
          float perpendicularVelocity = getPerpendicularVelocity(mVelocityTracker);

          // Decide whether to dismiss the current view
          // Tweak constants below as required to prevent erroneous
          // swipe/dismiss
          float translation = Math.abs(mCurrAnimView.getTranslationX());
          float currAnimViewSize = getSize(mCurrAnimView);
          // Long swipe = translation of .4 * width
          boolean childSwipedFarEnough =
              DISMISS_IF_SWIPED_FAR_ENOUGH && translation > 0.4 * currAnimViewSize;
          // Fast swipe = > escapeVelocity and translation of .1 *
          // width
          boolean childSwipedFastEnough =
              (Math.abs(velocity) > escapeVelocity)
                  && (Math.abs(velocity) > Math.abs(perpendicularVelocity))
                  && (velocity > 0) == (mCurrAnimView.getTranslationX() > 0)
                  && translation > 0.05 * currAnimViewSize;
          if (LOG_SWIPE_DISMISS_VELOCITY) {
            LogUtils.v(
                TAG,
                "Swipe/Dismiss: "
                    + velocity
                    + "/"
                    + escapeVelocity
                    + "/"
                    + perpendicularVelocity
                    + ", x: "
                    + translation
                    + "/"
                    + currAnimViewSize);
          }

          boolean dismissChild =
              mCallback.canChildBeDismissed(mCurrView)
                  && (childSwipedFastEnough || childSwipedFarEnough);

          if (dismissChild) {
            dismissChild(mCurrView, childSwipedFastEnough ? velocity : 0f);
          } else {
            snapChild(mCurrView);
          }
        }
        break;
    }
    return true;
  }
예제 #4
0
 public boolean onInterceptTouchEvent(MotionEvent ev) {
   final int action = ev.getAction();
   switch (action) {
     case MotionEvent.ACTION_DOWN:
       mLastY = ev.getY();
       mDragging = false;
       View view = mCallback.getChildAtPosition(ev);
       if (view instanceof SwipeableItemView) {
         mCurrView = (SwipeableItemView) view;
       } else {
         // If the touched item is not a swipeable one, clean the cache in
         // mCurrView to make sure nothing will be swiped for this action
         mCurrView = null;
       }
       mVelocityTracker.clear();
       if (mCurrView != null) {
         mCurrAnimView = mCurrView.getSwipeableView().getView();
         mCanCurrViewBeDimissed = mCallback.canChildBeDismissed(mCurrView);
         mVelocityTracker.addMovement(ev);
         mInitialTouchPosX = ev.getX();
         mInitialTouchPosY = ev.getY();
       }
       mCallback.cancelDismissCounter();
       break;
     case MotionEvent.ACTION_MOVE:
       if (mCurrView != null) {
         // Check the movement direction.
         if (mLastY >= 0 && !mDragging) {
           float currY = ev.getY();
           float currX = ev.getX();
           float deltaY = Math.abs(currY - mInitialTouchPosY);
           float deltaX = Math.abs(currX - mInitialTouchPosX);
           if (deltaY > mCurrView.getMinAllowScrollDistance() && deltaY > (FACTOR * deltaX)) {
             mLastY = ev.getY();
             mCallback.onScroll();
             return false;
           }
         }
         mVelocityTracker.addMovement(ev);
         float pos = ev.getX();
         float delta = pos - mInitialTouchPosX;
         if (Math.abs(delta) > mPagingTouchSlop) {
           mCallback.onBeginDrag(mCurrView.getSwipeableView().getView());
           mPrevView = mCallback.getLastSwipedItem();
           mDragging = true;
           mInitialTouchPosX = ev.getX() - mCurrAnimView.getTranslationX();
           mInitialTouchPosY = ev.getY();
         }
       }
       mLastY = ev.getY();
       break;
     case MotionEvent.ACTION_UP:
     case MotionEvent.ACTION_CANCEL:
       mDragging = false;
       mCurrView = null;
       mCurrAnimView = null;
       mLastY = -1;
       break;
   }
   return mDragging;
 }