@Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { Log.d("Fling", "Fling with " + velocityX + ", " + velocityY); final View topCard = mTopCard; float dx = e2.getX() - e1.getX(); if (Math.abs(dx) > mTouchSlop && Math.abs(velocityX) > Math.abs(velocityY) && Math.abs(velocityX) > mFlingSlop * 3) { float targetX = topCard.getX(); float targetY = topCard.getY(); long duration = 0; boundsRect.set( 0 - topCard.getWidth() - 100, 0 - topCard.getHeight() - 100, getWidth() + 100, getHeight() + 100); while (boundsRect.contains((int) targetX, (int) targetY)) { targetX += velocityX / 10; targetY += velocityY / 10; duration += 100; } duration = Math.min(500, duration); mTopCard = getChildAt(getChildCount() - 2); CardModel cardModel = (CardModel) getAdapter().getItem(getChildCount() - 1); if (mTopCard != null) mTopCard.setLayerType(LAYER_TYPE_HARDWARE, null); if (cardModel.getOnCardDismissedListener() != null) { if (targetX > 0) { cardModel.getOnCardDismissedListener().onLike(); } else { cardModel.getOnCardDismissedListener().onDislike(); } } topCard .animate() .setDuration(duration) .alpha(.75f) .setInterpolator(new LinearInterpolator()) .x(targetX) .y(targetY) .rotation(Math.copySign(45, velocityX)) .setListener( new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { removeViewInLayout(topCard); ensureFull(); } @Override public void onAnimationCancel(Animator animation) { onAnimationEnd(animation); } }); return true; } else return false; }
@Override public boolean onInterceptTouchEvent(MotionEvent event) { if (mTopCard == null) { return false; } if (mGestureDetector.onTouchEvent(event)) { return true; } final int pointerIndex; final float x, y; final float dx, dy; switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: mTopCard.getHitRect(childRect); CardModel cardModel = (CardModel) getAdapter().getItem(getChildCount() - 1); if (cardModel.getOnClickListener() != null) { cardModel.getOnClickListener().OnClickListener(); } pointerIndex = event.getActionIndex(); x = event.getX(pointerIndex); y = event.getY(pointerIndex); if (!childRect.contains((int) x, (int) y)) { return false; } mLastTouchX = x; mLastTouchY = y; mActivePointerId = event.getPointerId(pointerIndex); break; case MotionEvent.ACTION_MOVE: pointerIndex = event.findPointerIndex(mActivePointerId); x = event.getX(pointerIndex); y = event.getY(pointerIndex); if (Math.abs(x - mLastTouchX) > mTouchSlop || Math.abs(y - mLastTouchY) > mTouchSlop) { float[] points = new float[] {x - mTopCard.getLeft(), y - mTopCard.getTop()}; mTopCard.getMatrix().invert(mMatrix); mMatrix.mapPoints(points); mTopCard.setPivotX(points[0]); mTopCard.setPivotY(points[1]); return true; } } return false; }