private float getMotionEventY(MotionEvent ev, int activePointerId) { int index = MotionEventCompat.findPointerIndex(ev, activePointerId); if (index < 0) { return -1.0F; } return MotionEventCompat.getY(ev, index); }
private float getMotionEventY(@NonNull MotionEvent ev, int activePointerId) { final int index = MotionEventCompat.findPointerIndex(ev, activePointerId); if (index < 0) { return -1; } return MotionEventCompat.getY(ev, index); }
/** * Determine drag. * * @param ev the ev */ private void determineDrag(MotionEvent ev) { final int activePointerId = mActivePointerId; final int pointerIndex = getPointerIndex(ev, activePointerId); if (activePointerId == INVALID_POINTER) { return; } final float x = MotionEventCompat.getX(ev, pointerIndex); final float dx = x - mLastMotionX; final float xDiff = Math.abs(dx); final float y = MotionEventCompat.getY(ev, pointerIndex); final float dy = y - mLastMotionY; final float yDiff = Math.abs(dy); if (xDiff > (isMenuOpen() ? mTouchSlop / 2 : mTouchSlop) && xDiff > yDiff && thisSlideAllowed(dx)) { startDrag(); mLastMotionX = x; mLastMotionY = y; setScrollingCacheEnabled(true); // TODO add back in touch slop check } else if (xDiff > mTouchSlop) { mIsUnableToDrag = true; } }
private void onPointerUp(MotionEvent e) { final int actionIndex = MotionEventCompat.getActionIndex(e); if (MotionEventCompat.getPointerId(e, actionIndex) == mScrollPointerId) { // Pick a new pointer to pick up the slack. final int newIndex = actionIndex == 0 ? 1 : 0; mScrollPointerId = MotionEventCompat.getPointerId(e, newIndex); mInitialTouchX = mLastTouchX = (int) (MotionEventCompat.getX(e, newIndex) + 0.5f); mInitialTouchY = mLastTouchY = (int) (MotionEventCompat.getY(e, newIndex) + 0.5f); } }
private void onSecondaryPointerUp(MotionEvent ev) { final int pointerIndex = MotionEventCompat.getActionIndex(ev); final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex); if (pointerId == mActivePointerId) { // This was our active pointer going up. Choose a new // active pointer and adjust accordingly. final int newPointerIndex = pointerIndex == 0 ? 1 : 0; mLastMotionY = MotionEventCompat.getY(ev, newPointerIndex); mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex); } }
@Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (!mEnabled) { return false; } final int action = ev.getAction() & MotionEventCompat.ACTION_MASK; if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP || (action != MotionEvent.ACTION_DOWN && mIsUnableToDrag)) { endDrag(); return false; } switch (action) { case MotionEvent.ACTION_MOVE: determineDrag(ev); break; case MotionEvent.ACTION_DOWN: int index = MotionEventCompat.getActionIndex(ev); mActivePointerId = MotionEventCompat.getPointerId(ev, index); if (mActivePointerId == INVALID_POINTER) { break; } mLastMotionX = mInitialMotionX = MotionEventCompat.getX(ev, index); mLastMotionY = MotionEventCompat.getY(ev, index); if (thisTouchAllowed(ev)) { mIsBeingDragged = false; mIsUnableToDrag = false; if (isMenuOpen() && mViewBehind.menuTouchInQuickReturn(mContent, mCurItem, ev.getX() + mScrollX)) { mQuickReturn = true; } } else { mIsUnableToDrag = true; } break; case MotionEventCompat.ACTION_POINTER_UP: onSecondaryPointerUp(ev); break; } if (!mIsBeingDragged) { if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMovement(ev); } return mIsBeingDragged || mQuickReturn; }
private void onSecondaryPointerUp(MotionEvent var1) { int var2 = (var1.getAction() & '\uff00') >> 8; if (MotionEventCompat.getPointerId(var1, var2) == this.mActivePointerId) { byte var3; if (var2 == 0) { var3 = 1; } else { var3 = 0; } this.mLastMotionY = (int) MotionEventCompat.getY(var1, var3); this.mActivePointerId = MotionEventCompat.getPointerId(var1, var3); if (this.mVelocityTracker != null) { this.mVelocityTracker.clear(); } } }
private boolean onMoveTouchEvent(@NonNull MotionEvent event, int pointerIndex) { if (IsBeingDropped()) { return false; } final float y = MotionEventCompat.getY(event, pointerIndex); float diffY = y - mLastEventOffset; diffY /= 2; if (diffY >= 0 && !isRefreshEnable() || (diffY < 0 && !isLoadMoreEnable())) return false; mLastEventOffset = (int) y; if (!shouldIntercept((int) (mTotalOffset + diffY))) { sendUpEvent(); sendDownEvent(); return false; } if (offsetLayout(diffY)) { mTotalOffset += diffY; return true; } return false; }
public boolean onInterceptTouchEvent(MotionEvent var1) { boolean var4 = true; int var2 = var1.getAction(); if (var2 == 2 && this.mIsBeingDragged) { return true; } else if (this.getScrollY() == 0 && !ViewCompat.canScrollVertically(this, 1)) { return false; } else { switch (var2 & 255) { case 0: var2 = (int) var1.getY(); if (!this.inChild((int) var1.getX(), var2)) { this.mIsBeingDragged = false; this.recycleVelocityTracker(); } else { this.mLastMotionY = var2; this.mActivePointerId = MotionEventCompat.getPointerId(var1, 0); this.initOrResetVelocityTracker(); this.mVelocityTracker.addMovement(var1); if (this.mScroller.isFinished()) { var4 = false; } this.mIsBeingDragged = var4; this.startNestedScroll(2); } break; case 1: case 3: this.mIsBeingDragged = false; this.mActivePointerId = -1; this.recycleVelocityTracker(); this.stopNestedScroll(); break; case 2: var2 = this.mActivePointerId; if (var2 != -1) { int var3 = MotionEventCompat.findPointerIndex(var1, var2); if (var3 == -1) { Log.e("NestedScrollView", "Invalid pointerId=" + var2 + " in onInterceptTouchEvent"); } else { var2 = (int) MotionEventCompat.getY(var1, var3); if (Math.abs(var2 - this.mLastMotionY) > this.mTouchSlop && (this.getNestedScrollAxes() & 2) == 0) { this.mIsBeingDragged = true; this.mLastMotionY = var2; this.initVelocityTrackerIfNotExists(); this.mVelocityTracker.addMovement(var1); this.mNestedYOffset = 0; ViewParent var5 = this.getParent(); if (var5 != null) { var5.requestDisallowInterceptTouchEvent(true); } } } } case 4: case 5: default: break; case 6: this.onSecondaryPointerUp(var1); } return this.mIsBeingDragged; } }
@Override public boolean onInterceptTouchEvent(MotionEvent ev) { ensureTarget(); final int action = MotionEventCompat.getActionMasked(ev); if (mReturningToStart && action == MotionEvent.ACTION_DOWN) { mReturningToStart = false; } if (!isEnabled() || mReturningToStart) { // Fail fast if we're not in a state where a swipe is possible return false; } switch (action) { case MotionEvent.ACTION_DOWN: mLastMotionY = mInitialMotionY = ev.getY(); mActivePointerId = MotionEventCompat.getPointerId(ev, 0); mIsBeingDragged = false; mCurrPercentage = 0; mStartPoint = mInitialMotionY; // 这里用up/down记录子控件能否下拉,如果当前子控件不能上下滑动,但当手指按下并移动子控件时,控件就会变得可滑动 // 后面的一些处理不能直接使用canChildScrollUp/canChildScrollDown // 但仍存在问题:当数据不满一屏且设置可以上拉模式后,多次快速上拉会激发上拉加载 up = canChildScrollUp(); down = canChildScrollDown(); break; case MotionEvent.ACTION_MOVE: if (mActivePointerId == INVALID_POINTER) { Log.e(LOG_TAG, "Got ACTION_MOVE event but don't have an active pointer id."); return false; } final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); if (pointerIndex < 0) { Log.e(LOG_TAG, "Got ACTION_MOVE event but have an invalid active pointer id."); return false; } final float y = MotionEventCompat.getY(ev, pointerIndex); // final float yDiff = y - mInitialMotionY; final float yDiff = y - mStartPoint; // 若上个手势的方向和当前手势方向不一致,返回 if ((mLastDirection == Mode.PULL_FROM_START && yDiff < 0) || (mLastDirection == Mode.PULL_FROM_END && yDiff > 0)) { return false; } // 下拉或上拉时,子控件本身能够滑动时,记录当前手指位置,当其滑动到尽头时, // mStartPoint作为下拉刷新或上拉加载的手势起点 if ((canChildScrollUp() && yDiff > 0) || (canChildScrollDown() && yDiff < 0)) { mStartPoint = y; } // 下拉 if (yDiff > mTouchSlop) { // 若当前子控件能向下滑动,或者上个手势为上拉,则返回 if (canChildScrollUp() || mLastDirection == Mode.PULL_FROM_END) { mIsBeingDragged = false; return false; } if ((mMode == Mode.PULL_FROM_START) || (mMode == Mode.BOTH)) { mLastMotionY = y; mIsBeingDragged = true; mLastDirection = Mode.PULL_FROM_START; } } // 上拉 else if (-yDiff > mTouchSlop) { // 若当前子控件能向上滑动,或者上个手势为下拉,则返回 if (canChildScrollDown() || mLastDirection == Mode.PULL_FROM_START) { mIsBeingDragged = false; return false; } // 若子控件不能上下滑动,说明数据不足一屏,若不满屏不加载,返回 if (!up && !down && !loadNoFull) { mIsBeingDragged = false; return false; } if ((mMode == Mode.PULL_FROM_END) || (mMode == Mode.BOTH)) { mLastMotionY = y; mIsBeingDragged = true; mLastDirection = Mode.PULL_FROM_END; } } break; case MotionEventCompat.ACTION_POINTER_UP: onSecondaryPointerUp(ev); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: mIsBeingDragged = false; mCurrPercentage = 0; mActivePointerId = INVALID_POINTER; mLastDirection = Mode.DISABLED; break; } return mIsBeingDragged; }
@Override public boolean onTouchEvent(MotionEvent ev) { // Check if pause button is hit if (ev.getAction() == MotionEvent.ACTION_DOWN) { float touchX = ev.getX(); float touchY = ev.getY(); if (pauseBt.getRect().contains((int) touchX, (int) touchY)) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { // LeaveMemoryGame(); Intent itn; itn = new Intent(getApplicationContext(), PauseMenuActivity.class); startActivity(itn); } } final int pointerIndex = MotionEventCompat.getActionIndex(ev); final float x = MotionEventCompat.getX(ev, pointerIndex); final float y = MotionEventCompat.getY(ev, pointerIndex); PlayerTouchX = (int) x; PlayerTouchY = (int) y; if (!showCardsState) { if (currentSelectedRectIndex1 == -1 && currentSelectedRectIndex2 == -1 && (currentSelectedRectIndex1 = findSelectedRect()) != -1) // nothing is selected: read first { Log.w( "Warn", "Selected 111: " + currentSelectedRectIndex1 + " 2 is: " + currentSelectedRectIndex2); } else if (currentSelectedRectIndex1 != -1 && currentSelectedRectIndex2 == -1 && (currentSelectedRectIndex2 = findSelectedRect()) != -1) // selected 1: read second { // Log.w("Warn", "Selected 222: " + currentSelectedRectIndex2 + " 1 is " + // currentSelectedRectIndex1); // search for pairs // if (KeysArray[currentSelectedRectIndex1] == currentSelectedRectIndex2 && // KeysArray[currentSelectedRectIndex2] == currentSelectedRectIndex1) { if (cardList.get(currentSelectedRectIndex1).code == cardList.get(currentSelectedRectIndex2).code) { // Log.w("Warn", "Pair found"); SoundHandler.PlaySound(SoundHandler.correct_sound_id3); pairs++; if (pairs == (M * N) / 2) LeaveMemoryGame(); cardList.get(currentSelectedRectIndex1).turned = true; // reveal 'cards' cardList.get(currentSelectedRectIndex2).turned = true; currentSelectedRectIndex1 = -1; currentSelectedRectIndex2 = -1; } else // if no pairs found activate 'no select timer' { canSelectState = false; noSelectTimer = System.currentTimeMillis(); // start counting time.. } } else if (currentSelectedRectIndex1 != -1 && currentSelectedRectIndex2 != -1) { Log.w("Warn", "Cant Select, waiting timer.."); } } } return true; }
@Override public boolean onTouchEvent(MotionEvent ev) { final int action = MotionEventCompat.getActionMasked(ev); if (mReturningToStart && action == MotionEvent.ACTION_DOWN) { mReturningToStart = false; } if (!isEnabled() || mReturningToStart || canChildScrollUp()) { // Fail fast if we're not in a state where a swipe is possible return false; } switch (action) { case MotionEvent.ACTION_DOWN: mActivePointerId = MotionEventCompat.getPointerId(ev, 0); mIsBeingDragged = false; break; case MotionEvent.ACTION_MOVE: { final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); if (pointerIndex < 0) { Log.e(LOG_TAG, "Got ACTION_MOVE event but have an invalid active pointer id."); return false; } final float y = MotionEventCompat.getY(ev, pointerIndex); final float overscrollTop = (y - mInitialMotionY) * DRAG_RATE; if (mIsBeingDragged) { mProgress.showArrow(true); float originalDragPercent = overscrollTop / mTotalDragDistance; if (originalDragPercent < 0) { return false; } float dragPercent = Math.min(1f, Math.abs(originalDragPercent)); float adjustedPercent = (float) Math.max(dragPercent - .4, 0) * 5 / 3; float extraOS = Math.abs(overscrollTop) - mTotalDragDistance; float slingshotDist = mUsingCustomStart ? mSpinnerFinalOffset - mOriginalOffsetTop : mSpinnerFinalOffset; float tensionSlingshotPercent = Math.max(0, Math.min(extraOS, slingshotDist * 2) / slingshotDist); float tensionPercent = (float) ((tensionSlingshotPercent / 4) - Math.pow((tensionSlingshotPercent / 4), 2)) * 2f; float extraMove = (slingshotDist) * tensionPercent * 2; int targetY = mOriginalOffsetTop + (int) ((slingshotDist * dragPercent) + extraMove); // where 1.0f is a full circle if (mCircleView.getVisibility() != View.VISIBLE) { mCircleView.setVisibility(View.VISIBLE); } if (!mScale) { ViewCompat.setScaleX(mCircleView, 1f); ViewCompat.setScaleY(mCircleView, 1f); } if (overscrollTop < mTotalDragDistance) { if (mScale) { setAnimationProgress(overscrollTop / mTotalDragDistance); } if (mProgress.getAlpha() > STARTING_PROGRESS_ALPHA && !isAnimationRunning(mAlphaStartAnimation)) { // Animate the alpha startProgressAlphaStartAnimation(); } float strokeStart = adjustedPercent * .8f; mProgress.setStartEndTrim(0f, Math.min(MAX_PROGRESS_ANGLE, strokeStart)); mProgress.setArrowScale(Math.min(1f, adjustedPercent)); } else { if (mProgress.getAlpha() < MAX_ALPHA && !isAnimationRunning(mAlphaMaxAnimation)) { // Animate the alpha startProgressAlphaMaxAnimation(); } } float rotation = (-0.25f + .4f * adjustedPercent + tensionPercent * 2) * .5f; mProgress.setProgressRotation(rotation); setTargetOffsetTopAndBottom( targetY - mCurrentTargetOffsetTop, true /* requires update */); } break; } case MotionEventCompat.ACTION_POINTER_DOWN: { final int index = MotionEventCompat.getActionIndex(ev); mActivePointerId = MotionEventCompat.getPointerId(ev, index); break; } case MotionEventCompat.ACTION_POINTER_UP: onSecondaryPointerUp(ev); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: { if (mActivePointerId == INVALID_POINTER) { if (action == MotionEvent.ACTION_UP) { Log.e(LOG_TAG, "Got ACTION_UP event but don't have an active pointer id."); } return false; } final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); final float y = MotionEventCompat.getY(ev, pointerIndex); final float overscrollTop = (y - mInitialMotionY) * DRAG_RATE; mIsBeingDragged = false; if (overscrollTop > mTotalDragDistance) { setRefreshing(true, true /* notify */); } else { // cancel refresh mRefreshing = false; mProgress.setStartEndTrim(0f, 0f); Animation.AnimationListener listener = null; if (!mScale) { listener = new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) {} @Override public void onAnimationEnd(Animation animation) { if (!mScale) { startScaleDownAnimation(null); } } @Override public void onAnimationRepeat(Animation animation) {} }; } animateOffsetToStartPosition(mCurrentTargetOffsetTop, listener); mProgress.showArrow(false); } mActivePointerId = INVALID_POINTER; return false; } } return true; }
public boolean onTouchEvent(MotionEvent motionevent) { float f; float f1; int i2; int j2 = motionevent.getAction(); if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMovement(motionevent); boolean flag; int l; int k1; if ((j2 & 0xff) == 6) { flag = true; } else { flag = false; } if (flag) { l = MotionEventCompat.getActionIndex(motionevent); } else { l = -1; } i2 = MotionEventCompat.getPointerCount(motionevent); k1 = 0; f = 0.0F; float f2; for (f1 = 0.0F; k1 < i2; f1 = f2) { float f5 = f; f2 = f1; if (l != k1) { f2 = f1 + MotionEventCompat.getX(motionevent, k1); f5 = f + MotionEventCompat.getY(motionevent, k1); } k1++; f = f5; } int i; if (flag) { i = i2 - 1; } else { i = i2; } f1 /= i; f /= i; j2 & 0xff; JVM INSTR tableswitch 0 6: default 204 // 0 383 // 1 862 // 2 643 // 3 1136 // 4 204 // 5 213 // 6 239; goto _L1 _L2 _L3 _L4 _L5 _L1 _L6 _L7 _L1: return false; _L6: mLastFocusX = f1; mDownFocusX = f1; mLastFocusY = f; mDownFocusY = f; cancelTaps(); return false; _L7: mLastFocusX = f1; mDownFocusX = f1; mLastFocusY = f; mDownFocusY = f; mVelocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity); int i1 = MotionEventCompat.getActionIndex(motionevent); int j = MotionEventCompat.getPointerId(motionevent, i1); f = VelocityTrackerCompat.getXVelocity(mVelocityTracker, j); f1 = VelocityTrackerCompat.getYVelocity(mVelocityTracker, j); j = 0; while (j < i2) { if (j != i1) { int l1 = MotionEventCompat.getPointerId(motionevent, j); float f3 = VelocityTrackerCompat.getXVelocity(mVelocityTracker, l1); if (VelocityTrackerCompat.getYVelocity(mVelocityTracker, l1) * f1 + f3 * f < 0.0F) { mVelocityTracker.clear(); return false; } } j++; } goto _L8
@Override public boolean onTouchEvent(@NonNull MotionEvent ev) { if (!mIsBeingDragged) { return super.onTouchEvent(ev); } final int action = MotionEventCompat.getActionMasked(ev); switch (action) { case MotionEvent.ACTION_MOVE: { final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); if (pointerIndex < 0) { return false; } final float y = MotionEventCompat.getY(ev, pointerIndex); final float yDiff = y - mInitialMotionY; final float scrollTop = yDiff * DRAG_RATE; mCurrentDragPercent = scrollTop / mTotalDragDistance; if (mCurrentDragPercent < 0) { return false; } float boundedDragPercent = Math.min(1f, Math.abs(mCurrentDragPercent)); float extraOS = Math.abs(scrollTop) - mTotalDragDistance; float slingshotDist = mTotalDragDistance; float tensionSlingshotPercent = Math.max(0, Math.min(extraOS, slingshotDist * 2) / slingshotDist); float tensionPercent = (float) ((tensionSlingshotPercent / 4) - Math.pow((tensionSlingshotPercent / 4), 2)) * 2f; float extraMove = (slingshotDist) * tensionPercent / 2; int targetY = (int) ((slingshotDist * boundedDragPercent) + extraMove); mBaseRefreshView.setPercent(mCurrentDragPercent, true); setTargetOffsetTop(targetY - mCurrentOffsetTop, true); break; } case MotionEventCompat.ACTION_POINTER_DOWN: final int index = MotionEventCompat.getActionIndex(ev); mActivePointerId = MotionEventCompat.getPointerId(ev, index); break; case MotionEventCompat.ACTION_POINTER_UP: onSecondaryPointerUp(ev); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: { if (mActivePointerId == INVALID_POINTER) { return false; } final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); final float y = MotionEventCompat.getY(ev, pointerIndex); final float overScrollTop = (y - mInitialMotionY) * DRAG_RATE; mIsBeingDragged = false; if (overScrollTop > mTotalDragDistance) { setRefreshing(true, true); } else { mRefreshing = false; animateOffsetToStartPosition(); } mActivePointerId = INVALID_POINTER; return false; } } return true; }
@Override public boolean onTouchEvent(MotionEvent ev) { if (!mEnabled || !mIsDragging && !mLastTouchAllowed && !allowSlidingFromHereX(ev, mInitialX) && !allowSlidingFromHereY(ev, mInitialY)) { return false; } final int action = ev.getAction(); if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_OUTSIDE) { mLastTouchAllowed = false; } else { mLastTouchAllowed = true; } if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMovement(ev); switch (action & MotionEventCompat.ACTION_MASK) { case MotionEvent.ACTION_DOWN: completeScroll(); // Remember where the motion event started mLastX = mInitialX = ev.getX(); mLastY = mInitialY = ev.getY(); mActivePointerId = MotionEventCompat.getPointerId(ev, 0); break; case MotionEvent.ACTION_MOVE: if (!mIsDragging) { final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); if (pointerIndex == -1) { mActivePointerId = INVALID_POINTER; break; } final float x = MotionEventCompat.getX(ev, pointerIndex); final float xDiff = Math.abs(x - mLastX); final float y = MotionEventCompat.getY(ev, pointerIndex); final float yDiff = Math.abs(y - mLastY); if (xDiff > mTouchSlop && xDiff > yDiff) { mIsDragging = true; mLastX = x; setDrawingCacheEnabled(true); } else if (yDiff > mTouchSlop && yDiff > xDiff) { mIsDragging = true; mLastY = y; setDrawingCacheEnabled(true); } } if (mIsDragging) { // Scroll to follow the motion event final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); if (activePointerIndex == -1) { mActivePointerId = INVALID_POINTER; break; } final float x = MotionEventCompat.getX(ev, activePointerIndex); final float y = MotionEventCompat.getY(ev, activePointerIndex); final float deltaX = mLastX - x; final float deltaY = mLastY - y; mLastX = x; mLastY = y; final float oldScrollX = getScrollX(); final float oldScrollY = getScrollY(); float scrollX = oldScrollX + deltaX; float scrollY = oldScrollY + deltaY; // Log.d("Layer", String.format("Layer scrollX[%f],scrollY[%f]", scrollX, scrollY)); final float leftBound, rightBound; final float bottomBound, topBound; switch (mScreenSide) { case STICK_TO_LEFT: topBound = bottomBound = rightBound = 0; leftBound = getWidth(); // How far left we can scroll break; case STICK_TO_MIDDLE: topBound = getHeight(); bottomBound = -getHeight(); leftBound = getWidth(); rightBound = -getWidth(); break; case STICK_TO_RIGHT: rightBound = -getWidth(); topBound = bottomBound = leftBound = 0; break; case STICK_TO_TOP: topBound = getHeight(); bottomBound = rightBound = leftBound = 0; break; case STICK_TO_BOTTOM: topBound = rightBound = leftBound = 0; bottomBound = -getHeight(); break; default: topBound = bottomBound = rightBound = leftBound = 0; break; } if (scrollX > leftBound) { scrollX = leftBound; } else if (scrollX < rightBound) { scrollX = rightBound; } if (scrollY > topBound) { scrollY = topBound; } else if (scrollY < bottomBound) { scrollY = bottomBound; } // Keep the precision mLastX += scrollX - (int) scrollX; mLastY += scrollY - (int) scrollY; scrollTo((int) scrollX, (int) scrollY); } break; case MotionEvent.ACTION_UP: if (mIsDragging) { final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); final int initialVelocityX = (int) VelocityTrackerCompat.getXVelocity(velocityTracker, mActivePointerId); final int initialVelocityY = (int) VelocityTrackerCompat.getYVelocity(velocityTracker, mActivePointerId); final int scrollX = getScrollX(); final int scrollY = getScrollY(); final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); final float x = MotionEventCompat.getX(ev, activePointerIndex); final float y = MotionEventCompat.getY(ev, activePointerIndex); final int totalDeltaX = (int) (x - mInitialX); final int totalDeltaY = (int) (y - mInitialY); boolean nextStateOpened = determineNextStateOpened( mIsOpen, scrollX, scrollY, initialVelocityX, initialVelocityY, totalDeltaX, totalDeltaY); switchLayer(nextStateOpened, true, true, initialVelocityX, initialVelocityY); mActivePointerId = INVALID_POINTER; endDrag(); } else if (mIsOpen && closeOnTapEnabled) { closeLayer(true); } else if (!mIsOpen && openOnTapEnabled) { openLayer(true); } break; case MotionEvent.ACTION_CANCEL: if (mIsDragging) { switchLayer(mIsOpen, true, true); mActivePointerId = INVALID_POINTER; endDrag(); } break; case MotionEventCompat.ACTION_POINTER_DOWN: { final int index = MotionEventCompat.getActionIndex(ev); mLastX = MotionEventCompat.getX(ev, index); mLastY = MotionEventCompat.getY(ev, index); mActivePointerId = MotionEventCompat.getPointerId(ev, index); break; } case MotionEventCompat.ACTION_POINTER_UP: onSecondaryPointerUp(ev); mLastX = MotionEventCompat.getX(ev, MotionEventCompat.findPointerIndex(ev, mActivePointerId)); mLastY = MotionEventCompat.getY(ev, MotionEventCompat.findPointerIndex(ev, mActivePointerId)); break; } if (mActivePointerId == INVALID_POINTER) { mLastTouchAllowed = false; } return true; }
@Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (!mIsFlippingEnabled) { return false; } if (mPageCount < 1) { return false; } final int action = ev.getAction() & MotionEvent.ACTION_MASK; if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) { mIsFlipping = false; mIsUnableToFlip = false; mActivePointerId = INVALID_POINTER; if (mVelocityTracker != null) { mVelocityTracker.recycle(); mVelocityTracker = null; } return false; } if (action != MotionEvent.ACTION_DOWN) { if (mIsFlipping) { return true; } else if (mIsUnableToFlip) { return false; } } switch (action) { case MotionEvent.ACTION_MOVE: final int activePointerId = mActivePointerId; if (activePointerId == INVALID_POINTER) { break; } final int pointerIndex = MotionEventCompat.findPointerIndex(ev, activePointerId); if (pointerIndex == -1) { mActivePointerId = INVALID_POINTER; break; } final float x = MotionEventCompat.getX(ev, pointerIndex); final float dx = x - mLastX; final float xDiff = Math.abs(dx); final float y = MotionEventCompat.getY(ev, pointerIndex); final float dy = y - mLastY; final float yDiff = Math.abs(dy); if ((mIsFlippingVertically && yDiff > mTouchSlop && yDiff > xDiff) || (!mIsFlippingVertically && xDiff > mTouchSlop && xDiff > yDiff)) { mIsFlipping = true; mLastX = x; mLastY = y; } else if ((mIsFlippingVertically && xDiff > mTouchSlop) || (!mIsFlippingVertically && yDiff > mTouchSlop)) { mIsUnableToFlip = true; } break; case MotionEvent.ACTION_DOWN: mActivePointerId = ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK; mLastX = MotionEventCompat.getX(ev, mActivePointerId); mLastY = MotionEventCompat.getY(ev, mActivePointerId); mIsFlipping = !mScroller.isFinished() | mPeakAnim != null; mIsUnableToFlip = false; mLastTouchAllowed = true; break; case MotionEventCompat.ACTION_POINTER_UP: onSecondaryPointerUp(ev); break; } if (!mIsFlipping) { trackVelocity(ev); } return mIsFlipping; }
@Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (!mEnabled) return false; final int action = ev.getAction() & MotionEventCompat.ACTION_MASK; if (action == MotionEvent.ACTION_DOWN && DEBUG) Log.v(TAG, "Received ACTION_DOWN"); if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP || (action != MotionEvent.ACTION_DOWN && mIsUnableToDrag)) { endDrag(); return false; } switch (action) { case MotionEvent.ACTION_MOVE: try { final int activePointerId = mActivePointerId; if (activePointerId == INVALID_POINTER) break; final int pointerIndex = this.getPointerIndex(ev, activePointerId); final float x = MotionEventCompat.getX(ev, pointerIndex); final float dx = x - mLastMotionX; final float xDiff = Math.abs(dx); final float y = MotionEventCompat.getY(ev, pointerIndex); final float yDiff = Math.abs(y - mLastMotionY); if (DEBUG) Log.v( TAG, "onInterceptTouch moved to:(" + x + ", " + y + "), diff:(" + xDiff + ", " + yDiff + "), mLastMotionX:" + mLastMotionX); if (xDiff > mTouchSlop && xDiff > yDiff && thisSlideAllowed(dx)) { if (DEBUG) Log.v(TAG, "Starting drag! from onInterceptTouch"); startDrag(); mLastMotionX = x; setScrollingCacheEnabled(true); } else if (yDiff > mTouchSlop) { mIsUnableToDrag = true; } } catch (IllegalArgumentException e) { e.printStackTrace(); } break; case MotionEvent.ACTION_DOWN: mActivePointerId = ev.getAction() & ((Build.VERSION.SDK_INT >= 8) ? MotionEvent.ACTION_POINTER_INDEX_MASK : MotionEvent.ACTION_POINTER_INDEX_MASK); mLastMotionX = mInitialMotionX = MotionEventCompat.getX(ev, mActivePointerId); mLastMotionY = MotionEventCompat.getY(ev, mActivePointerId); if (thisTouchAllowed(ev)) { mIsBeingDragged = false; mIsUnableToDrag = false; if (isMenuOpen() && mViewBehind.menuTouchInQuickReturn(mContent, mCurItem, ev.getX() + mScrollX)) { mQuickReturn = true; } } else { mIsUnableToDrag = true; } break; case MotionEventCompat.ACTION_POINTER_UP: onSecondaryPointerUp(ev); break; } if (!mIsBeingDragged) { if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMovement(ev); } return mIsBeingDragged || mQuickReturn; }
public boolean onTouchEvent(MotionEvent var1) { this.initVelocityTrackerIfNotExists(); MotionEvent var9 = MotionEvent.obtain(var1); int var2 = MotionEventCompat.getActionMasked(var1); if (var2 == 0) { this.mNestedYOffset = 0; } var9.offsetLocation(0.0F, (float) this.mNestedYOffset); ViewParent var10; switch (var2) { case 0: if (this.getChildCount() == 0) { return false; } boolean var8; if (!this.mScroller.isFinished()) { var8 = true; } else { var8 = false; } this.mIsBeingDragged = var8; if (var8) { var10 = this.getParent(); if (var10 != null) { var10.requestDisallowInterceptTouchEvent(true); } } if (!this.mScroller.isFinished()) { this.mScroller.abortAnimation(); } this.mLastMotionY = (int) var1.getY(); this.mActivePointerId = MotionEventCompat.getPointerId(var1, 0); this.startNestedScroll(2); break; case 1: if (this.mIsBeingDragged) { VelocityTracker var11 = this.mVelocityTracker; var11.computeCurrentVelocity(1000, (float) this.mMaximumVelocity); var2 = (int) VelocityTrackerCompat.getYVelocity(var11, this.mActivePointerId); if (Math.abs(var2) > this.mMinimumVelocity) { this.flingWithNestedDispatch(-var2); } this.mActivePointerId = -1; this.endDrag(); } break; case 2: int var4 = MotionEventCompat.findPointerIndex(var1, this.mActivePointerId); if (var4 == -1) { Log.e( "NestedScrollView", "Invalid pointerId=" + this.mActivePointerId + " in onTouchEvent"); } else { int var5 = (int) MotionEventCompat.getY(var1, var4); var2 = this.mLastMotionY - var5; int var3 = var2; if (this.dispatchNestedPreScroll(0, var2, this.mScrollConsumed, this.mScrollOffset)) { var3 = var2 - this.mScrollConsumed[1]; var9.offsetLocation(0.0F, (float) this.mScrollOffset[1]); this.mNestedYOffset += this.mScrollOffset[1]; } var2 = var3; if (!this.mIsBeingDragged) { var2 = var3; if (Math.abs(var3) > this.mTouchSlop) { var10 = this.getParent(); if (var10 != null) { var10.requestDisallowInterceptTouchEvent(true); } this.mIsBeingDragged = true; if (var3 > 0) { var2 = var3 - this.mTouchSlop; } else { var2 = var3 + this.mTouchSlop; } } } if (this.mIsBeingDragged) { this.mLastMotionY = var5 - this.mScrollOffset[1]; int var6 = this.getScrollY(); var5 = this.getScrollRange(); var3 = ViewCompat.getOverScrollMode(this); boolean var12; if (var3 != 0 && (var3 != 1 || var5 <= 0)) { var12 = false; } else { var12 = true; } if (this.overScrollByCompat(0, var2, 0, this.getScrollY(), 0, var5, 0, 0, true) && !this.hasNestedScrollingParent()) { this.mVelocityTracker.clear(); } int var7 = this.getScrollY() - var6; if (this.dispatchNestedScroll(0, var7, 0, var2 - var7, this.mScrollOffset)) { this.mLastMotionY -= this.mScrollOffset[1]; var9.offsetLocation(0.0F, (float) this.mScrollOffset[1]); this.mNestedYOffset += this.mScrollOffset[1]; } else if (var12) { this.ensureGlows(); var3 = var6 + var2; if (var3 < 0) { this.mEdgeGlowTop.onPull( (float) var2 / (float) this.getHeight(), MotionEventCompat.getX(var1, var4) / (float) this.getWidth()); if (!this.mEdgeGlowBottom.isFinished()) { this.mEdgeGlowBottom.onRelease(); } } else if (var3 > var5) { this.mEdgeGlowBottom.onPull( (float) var2 / (float) this.getHeight(), 1.0F - MotionEventCompat.getX(var1, var4) / (float) this.getWidth()); if (!this.mEdgeGlowTop.isFinished()) { this.mEdgeGlowTop.onRelease(); } } if (this.mEdgeGlowTop != null && (!this.mEdgeGlowTop.isFinished() || !this.mEdgeGlowBottom.isFinished())) { ViewCompat.postInvalidateOnAnimation(this); } } } } break; case 3: if (this.mIsBeingDragged && this.getChildCount() > 0) { this.mActivePointerId = -1; this.endDrag(); } case 4: default: break; case 5: var2 = MotionEventCompat.getActionIndex(var1); this.mLastMotionY = (int) MotionEventCompat.getY(var1, var2); this.mActivePointerId = MotionEventCompat.getPointerId(var1, var2); break; case 6: this.onSecondaryPointerUp(var1); this.mLastMotionY = (int) MotionEventCompat.getY( var1, MotionEventCompat.findPointerIndex(var1, this.mActivePointerId)); } if (this.mVelocityTracker != null) { this.mVelocityTracker.addMovement(var9); } var9.recycle(); return true; }
@Override public boolean onTouchEvent(MotionEvent ev) { // return or not? mScaleDetector.onTouchEvent(ev); mGestureDetector.onTouchEvent(ev); final int action = MotionEventCompat.getActionMasked(ev); switch (action) { case MotionEvent.ACTION_DOWN: { final int pointerIndex = MotionEventCompat.getActionIndex(ev); final float x = MotionEventCompat.getX(ev, pointerIndex); final float y = MotionEventCompat.getY(ev, pointerIndex); int index = getActiveIndexByXY(x, y); if (index >= 0) { mActiveIndex = index; mLastTouchX = x; mLastTouchY = y; mActivePointerId = MotionEventCompat.getPointerId(ev, 0); } break; } case MotionEvent.ACTION_MOVE: if (mActivePointerId != INVALID_POINTER_ID) { final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); final float x = MotionEventCompat.getX(ev, pointerIndex); final float y = MotionEventCompat.getY(ev, pointerIndex); final float dx = x - mLastTouchX; final float dy = y - mLastTouchY; Figure figure = mFigures.get(mActiveIndex); figure.x += dx; figure.y += dy; mLastTouchX = x; mLastTouchY = y; invalidate(); } break; case MotionEvent.ACTION_UP: { if (mActiveIndex >= 0) { if (mUpdateFigureListener != null) { mUpdateFigureListener.onUpdate(mFigures.get(mActiveIndex)); } mActiveIndex = -1; } mActivePointerId = INVALID_POINTER_ID; break; } case MotionEvent.ACTION_CANCEL: { mActivePointerId = INVALID_POINTER_ID; mActiveIndex = -1; break; } case MotionEvent.ACTION_POINTER_UP: final int pointerIndex = MotionEventCompat.getActionIndex(ev); final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex); if (pointerId == mActivePointerId) { final int newPointerIndex = pointerIndex == 0 ? 1 : 0; mLastTouchX = MotionEventCompat.getX(ev, newPointerIndex); mLastTouchY = MotionEventCompat.getY(ev, newPointerIndex); mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex); } break; } return true; }
@Override public boolean onInterceptTouchEvent(MotionEvent e) { final boolean canScrollHorizontally = false; // mLayout.canScrollHorizontally(); final boolean canScrollVertically = true; // mLayout.canScrollVertically(); if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMovement(e); final int action = MotionEventCompat.getActionMasked(e); final int actionIndex = MotionEventCompat.getActionIndex(e); switch (action) { case MotionEvent.ACTION_DOWN: if (mIgnoreMotionEventTillDown) { mIgnoreMotionEventTillDown = false; } mScrollPointerId = MotionEventCompat.getPointerId(e, 0); mInitialTouchX = mLastTouchX = (int) (e.getX() + 0.5f); mInitialTouchY = mLastTouchY = (int) (e.getY() + 0.5f); if (mScrollState == SCROLL_STATE_SETTLING) { getParent().requestDisallowInterceptTouchEvent(true); setScrollState(SCROLL_STATE_DRAGGING); } // Clear the nested offsets mNestedOffsets[0] = mNestedOffsets[1] = 0; int nestedScrollAxis = ViewCompat.SCROLL_AXIS_NONE; if (canScrollHorizontally) { nestedScrollAxis |= ViewCompat.SCROLL_AXIS_HORIZONTAL; } if (canScrollVertically) { nestedScrollAxis |= ViewCompat.SCROLL_AXIS_VERTICAL; } startNestedScroll(nestedScrollAxis); break; case MotionEventCompat.ACTION_POINTER_DOWN: mScrollPointerId = MotionEventCompat.getPointerId(e, actionIndex); mInitialTouchX = mLastTouchX = (int) (MotionEventCompat.getX(e, actionIndex) + 0.5f); mInitialTouchY = mLastTouchY = (int) (MotionEventCompat.getY(e, actionIndex) + 0.5f); break; case MotionEvent.ACTION_MOVE: { final int index = MotionEventCompat.findPointerIndex(e, mScrollPointerId); if (index < 0) { Log.e( TAG, "Error processing scroll; pointer index for id " + mScrollPointerId + " not found. Did any MotionEvents get skipped?"); return false; } final int x = (int) (MotionEventCompat.getX(e, index) + 0.5f); final int y = (int) (MotionEventCompat.getY(e, index) + 0.5f); if (mScrollState != SCROLL_STATE_DRAGGING) { final int dx = x - mInitialTouchX; final int dy = y - mInitialTouchY; boolean startScroll = false; if (canScrollHorizontally && Math.abs(dx) > mTouchSlop) { mLastTouchX = mInitialTouchX + mTouchSlop * (dx < 0 ? -1 : 1); startScroll = true; } if (canScrollVertically && Math.abs(dy) > mTouchSlop) { mLastTouchY = mInitialTouchY + mTouchSlop * (dy < 0 ? -1 : 1); startScroll = true; } if (startScroll) { setScrollState(SCROLL_STATE_DRAGGING); } } } break; case MotionEventCompat.ACTION_POINTER_UP: { onPointerUp(e); } break; case MotionEvent.ACTION_UP: { mVelocityTracker.clear(); stopNestedScroll(); } break; case MotionEvent.ACTION_CANCEL: { cancelTouch(); } } return mScrollState == SCROLL_STATE_DRAGGING; }
@Override public boolean onTouchEvent(MotionEvent ev) { if (!mIsFlippingEnabled) { return false; } if (mPageCount < 1) { return false; } if (!mIsFlipping && !mLastTouchAllowed) { return false; } final int action = ev.getAction(); if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_OUTSIDE) { mLastTouchAllowed = false; } else { mLastTouchAllowed = true; } trackVelocity(ev); switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: // start flipping immediately if interrupting some sort of animation if (endScroll() || endPeak()) { mIsFlipping = true; } // Remember where the motion event started mLastX = ev.getX(); mLastY = ev.getY(); mActivePointerId = MotionEventCompat.getPointerId(ev, 0); break; case MotionEvent.ACTION_MOVE: if (!mIsFlipping) { final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); if (pointerIndex == -1) { mActivePointerId = INVALID_POINTER; break; } final float x = MotionEventCompat.getX(ev, pointerIndex); final float xDiff = Math.abs(x - mLastX); final float y = MotionEventCompat.getY(ev, pointerIndex); final float yDiff = Math.abs(y - mLastY); if ((mIsFlippingVertically && yDiff > mTouchSlop && yDiff > xDiff) || (!mIsFlippingVertically && xDiff > mTouchSlop && xDiff > yDiff)) { mIsFlipping = true; mLastX = x; mLastY = y; } } if (mIsFlipping) { // Scroll to follow the motion event final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); if (activePointerIndex == -1) { mActivePointerId = INVALID_POINTER; break; } final float x = MotionEventCompat.getX(ev, activePointerIndex); final float deltaX = mLastX - x; final float y = MotionEventCompat.getY(ev, activePointerIndex); final float deltaY = mLastY - y; mLastX = x; mLastY = y; float deltaFlipDistance = 0; if (mIsFlippingVertically) { deltaFlipDistance = deltaY; } else { deltaFlipDistance = deltaX; } deltaFlipDistance /= ((isFlippingVertically() ? getHeight() : getWidth()) / FLIP_DISTANCE_PER_PAGE); setFlipDistance(mFlipDistance + deltaFlipDistance); final int minFlipDistance = 0; final int maxFlipDistance = (mPageCount - 1) * FLIP_DISTANCE_PER_PAGE; final boolean isOverFlipping = mFlipDistance < minFlipDistance || mFlipDistance > maxFlipDistance; if (isOverFlipping) { mIsOverFlipping = true; setFlipDistance( mOverFlipper.calculate(mFlipDistance, minFlipDistance, maxFlipDistance)); if (mOnOverFlipListener != null) { float overFlip = mOverFlipper.getTotalOverFlip(); mOnOverFlipListener.onOverFlip( this, mOverFlipMode, overFlip < 0, Math.abs(overFlip), FLIP_DISTANCE_PER_PAGE); } } else if (mIsOverFlipping) { mIsOverFlipping = false; if (mOnOverFlipListener != null) { // TODO in the future should only notify flip distance 0 // on the correct edge (previous/next) mOnOverFlipListener.onOverFlip(this, mOverFlipMode, false, 0, FLIP_DISTANCE_PER_PAGE); mOnOverFlipListener.onOverFlip(this, mOverFlipMode, true, 0, FLIP_DISTANCE_PER_PAGE); } } } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: if (mIsFlipping) { final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); int velocity = 0; if (isFlippingVertically()) { velocity = (int) VelocityTrackerCompat.getYVelocity(velocityTracker, mActivePointerId); } else { velocity = (int) VelocityTrackerCompat.getXVelocity(velocityTracker, mActivePointerId); } smoothFlipTo(getNextPage(velocity)); mActivePointerId = INVALID_POINTER; endFlip(); mOverFlipper.overFlipEnded(); } break; case MotionEventCompat.ACTION_POINTER_DOWN: { final int index = MotionEventCompat.getActionIndex(ev); final float x = MotionEventCompat.getX(ev, index); final float y = MotionEventCompat.getY(ev, index); mLastX = x; mLastY = y; mActivePointerId = MotionEventCompat.getPointerId(ev, index); break; } case MotionEventCompat.ACTION_POINTER_UP: onSecondaryPointerUp(ev); final int index = MotionEventCompat.findPointerIndex(ev, mActivePointerId); final float x = MotionEventCompat.getX(ev, index); final float y = MotionEventCompat.getY(ev, index); mLastX = x; mLastY = y; break; } if (mActivePointerId == INVALID_POINTER) { mLastTouchAllowed = false; } return true; }
@Override public boolean onTouchEvent(MotionEvent ev) { final int action = MotionEventCompat.getActionMasked(ev); if (mReturningToStart && action == MotionEvent.ACTION_DOWN) { mReturningToStart = false; } if (!isEnabled() || mReturningToStart) { // Fail fast if we're not in a state where a swipe is possible return false; } switch (action) { case MotionEvent.ACTION_DOWN: mLastMotionY = mInitialMotionY = ev.getY(); mActivePointerId = MotionEventCompat.getPointerId(ev, 0); mIsBeingDragged = false; mCurrPercentage = 0; mStartPoint = mInitialMotionY; up = canChildScrollUp(); down = canChildScrollDown(); break; case MotionEvent.ACTION_MOVE: final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); if (pointerIndex < 0) { Log.e(LOG_TAG, "Got ACTION_MOVE event but have an invalid active pointer id."); return false; } final float y = MotionEventCompat.getY(ev, pointerIndex); // final float yDiff = y - mInitialMotionY; final float yDiff = y - mStartPoint; if ((mLastDirection == Mode.PULL_FROM_START && yDiff < 0) || (mLastDirection == Mode.PULL_FROM_END && yDiff > 0)) { return true; } if (!mIsBeingDragged && (yDiff > 0 && mLastDirection == Mode.PULL_FROM_START) || (yDiff < 0 && mLastDirection == Mode.PULL_FROM_END)) { mIsBeingDragged = true; } if (mIsBeingDragged) { // User velocity passed min velocity; trigger a refresh if (yDiff > mDistanceToTriggerSync) { // User movement passed distance; trigger a refresh if (mLastDirection == Mode.PULL_FROM_END) { return true; } if ((mMode == Mode.PULL_FROM_START) || (mMode == Mode.BOTH)) { mLastDirection = Mode.PULL_FROM_START; startRefresh(); } } else if (-yDiff > mDistanceToTriggerSync) { if ((!up && !down && !loadNoFull) || mLastDirection == Mode.PULL_FROM_START) { return true; } if ((mMode == Mode.PULL_FROM_END) || (mMode == Mode.BOTH)) { mLastDirection = Mode.PULL_FROM_END; startLoad(); } } else { if (!up && !down && yDiff < 0 && !loadNoFull) { return true; } // Just track the user's movement // 根据手指移动距离设置进度条显示的百分比 setTriggerPercentage( mAccelerateInterpolator.getInterpolation(Math.abs(yDiff) / mDistanceToTriggerSync)); updateContentOffsetTop((int) yDiff); if (mTarget.getTop() == getPaddingTop()) { // If the user puts the view back at the top, we // don't need to. This shouldn't be considered // cancelling the gesture as the user can restart from the top. removeCallbacks(mCancel); mLastDirection = Mode.DISABLED; } else { mDirection = (yDiff > 0 ? 1 : -1); updatePositionTimeout(); } } mLastMotionY = y; } break; case MotionEventCompat.ACTION_POINTER_DOWN: { final int index = MotionEventCompat.getActionIndex(ev); mLastMotionY = MotionEventCompat.getY(ev, index); mActivePointerId = MotionEventCompat.getPointerId(ev, index); break; } case MotionEventCompat.ACTION_POINTER_UP: onSecondaryPointerUp(ev); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: mIsBeingDragged = false; mCurrPercentage = 0; mActivePointerId = INVALID_POINTER; mLastDirection = Mode.DISABLED; return false; } return true; }
@Override public boolean onTouchEvent(MotionEvent ev) { if (!mEnabled) return false; if (!mIsBeingDragged && !thisTouchAllowed(ev)) return false; // if (!mIsBeingDragged && !mQuickReturn) // return false; final int action = ev.getAction(); if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMovement(ev); switch (action & MotionEventCompat.ACTION_MASK) { case MotionEvent.ACTION_DOWN: /* * If being flinged and user touches, stop the fling. isFinished * will be false if being flinged. */ completeScroll(); // Remember where the motion event started int index = MotionEventCompat.getActionIndex(ev); mActivePointerId = MotionEventCompat.getPointerId(ev, index); if (mViewBehind.getbMode()) { mLastMotionX = mInitialMotionX = ev.getY(); } else { mLastMotionX = mInitialMotionX = ev.getX(); } break; case MotionEvent.ACTION_MOVE: if (!mIsBeingDragged) { determineDrag(ev); if (mIsUnableToDrag) return false; } if (mIsBeingDragged) { // Scroll to follow the motion event final int activePointerIndex = getPointerIndex(ev, mActivePointerId); if (mActivePointerId == INVALID_POINTER) break; if (mViewBehind.getbMode()) { final float y = MotionEventCompat.getY(ev, activePointerIndex); final float deltaY = mLastMotionY - y; mLastMotionY = y; float oldScrollY = getScrollY(); float scrollY = oldScrollY + deltaY; final float leftBound = getLeftBound(); final float rightBound = getRightBound(); if (scrollY < leftBound) { scrollY = leftBound; } else if (scrollY > rightBound) { scrollY = rightBound; } // Don't lose the rounded component mLastMotionY += scrollY - (int) scrollY; scrollTo(getScrollX(), (int) scrollY); pageScrolled((int) scrollY); } else { final float x = MotionEventCompat.getX(ev, activePointerIndex); final float deltaX = mLastMotionX - x; mLastMotionX = x; float oldScrollX = getScrollX(); float scrollX = oldScrollX + deltaX; final float leftBound = getLeftBound(); final float rightBound = getRightBound(); if (scrollX < leftBound) { scrollX = leftBound; } else if (scrollX > rightBound) { scrollX = rightBound; } // Don't lose the rounded component mLastMotionX += scrollX - (int) scrollX; scrollTo((int) scrollX, getScrollY()); pageScrolled((int) scrollX); } } break; case MotionEvent.ACTION_UP: if (mIsBeingDragged) { final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); if (mViewBehind.getbMode()) { int initialVelocity = (int) VelocityTrackerCompat.getYVelocity(velocityTracker, mActivePointerId); final int scrollY = getScrollY(); final float pageOffset = (float) (scrollY - getDestScrollX(mCurItem)) / getBehindWidth(); final int activePointerIndex = getPointerIndex(ev, mActivePointerId); if (mActivePointerId != INVALID_POINTER) { final float y = MotionEventCompat.getY(ev, activePointerIndex); final int totalDelta = (int) (y - mInitialMotionX); int nextPage = determineTargetPage(pageOffset, initialVelocity, totalDelta); setCurrentItemInternal(nextPage, true, true, initialVelocity); } else { setCurrentItemInternal(mCurItem, true, true, initialVelocity); } } else { int initialVelocity = (int) VelocityTrackerCompat.getXVelocity(velocityTracker, mActivePointerId); final int scrollX = getScrollX(); final float pageOffset = (float) (scrollX - getDestScrollX(mCurItem)) / getBehindWidth(); final int activePointerIndex = getPointerIndex(ev, mActivePointerId); if (mActivePointerId != INVALID_POINTER) { final float x = MotionEventCompat.getX(ev, activePointerIndex); final int totalDelta = (int) (x - mInitialMotionX); int nextPage = determineTargetPage(pageOffset, initialVelocity, totalDelta); setCurrentItemInternal(nextPage, true, true, initialVelocity); } else { setCurrentItemInternal(mCurItem, true, true, initialVelocity); } } mActivePointerId = INVALID_POINTER; endDrag(); } else if (mQuickReturn && mViewBehind.menuTouchInQuickReturn(mContent, mCurItem, ev.getX() + mScrollX)) { // close the menu setCurrentItem(1); endDrag(); } break; case MotionEvent.ACTION_CANCEL: if (mIsBeingDragged) { setCurrentItemInternal(mCurItem, true, true); mActivePointerId = INVALID_POINTER; endDrag(); } break; case MotionEventCompat.ACTION_POINTER_DOWN: { final int indexx = MotionEventCompat.getActionIndex(ev); if (mViewBehind.getbMode()) { mLastMotionY = MotionEventCompat.getY(ev, indexx); } else { mLastMotionX = MotionEventCompat.getX(ev, indexx); } mActivePointerId = MotionEventCompat.getPointerId(ev, indexx); break; } case MotionEventCompat.ACTION_POINTER_UP: onSecondaryPointerUp(ev); int pointerIndex = getPointerIndex(ev, mActivePointerId); if (mActivePointerId == INVALID_POINTER) break; if (mViewBehind.getbMode()) { mLastMotionY = MotionEventCompat.getY(ev, pointerIndex); } else { mLastMotionX = MotionEventCompat.getX(ev, pointerIndex); } break; } return true; }
@Override public boolean onTouchEvent(MotionEvent ev) { final int action = MotionEventCompat.getActionMasked(ev); if (mReturningToStart && action == MotionEvent.ACTION_DOWN) { mReturningToStart = false; } if (!isEnabled() || mReturningToStart || canChildScrollUp()) { // Fail fast if we're not in a state where a swipe is possible return false; } switch (action) { case MotionEvent.ACTION_DOWN: mActivePointerId = MotionEventCompat.getPointerId(ev, 0); mIsBeingDragged = false; break; case MotionEvent.ACTION_MOVE: { final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); if (pointerIndex < 0) { Log.e(LOG_TAG, "Got ACTION_MOVE event but have an invalid active pointer id."); return false; } final float y = MotionEventCompat.getY(ev, pointerIndex); final float overscrollTop = (y - mInitialMotionY) * DRAG_RATE; if (mIsBeingDragged) { if (overscrollTop > 0) { moveSpinner(overscrollTop); } else { return false; } } break; } case MotionEventCompat.ACTION_POINTER_DOWN: { final int index = MotionEventCompat.getActionIndex(ev); mActivePointerId = MotionEventCompat.getPointerId(ev, index); break; } case MotionEventCompat.ACTION_POINTER_UP: onSecondaryPointerUp(ev); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: { if (mActivePointerId == INVALID_POINTER) { if (action == MotionEvent.ACTION_UP) { Log.e(LOG_TAG, "Got ACTION_UP event but don't have an active pointer id."); } return false; } final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); final float y = MotionEventCompat.getY(ev, pointerIndex); final float overscrollTop = (y - mInitialMotionY) * DRAG_RATE; mIsBeingDragged = false; finishSpinner(overscrollTop); mActivePointerId = INVALID_POINTER; return false; } } return true; }
@Override public boolean onTouchEvent(MotionEvent e) { /* if (mLayoutFrozen || mIgnoreMotionEventTillDown) { return false; } if (dispatchOnItemTouch(e)) { cancelTouch(); return true; } if (mLayout == null) { return false; } */ final boolean canScrollHorizontally = false; // mLayout.canScrollHorizontally(); final boolean canScrollVertically = true; // mLayout.canScrollVertically(); if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } boolean eventAddedToVelocityTracker = false; final MotionEvent vtev = MotionEvent.obtain(e); final int action = MotionEventCompat.getActionMasked(e); final int actionIndex = MotionEventCompat.getActionIndex(e); if (action == MotionEvent.ACTION_DOWN) { mNestedOffsets[0] = mNestedOffsets[1] = 0; } vtev.offsetLocation(mNestedOffsets[0], mNestedOffsets[1]); switch (action) { case MotionEvent.ACTION_DOWN: { mScrollPointerId = MotionEventCompat.getPointerId(e, 0); mInitialTouchX = mLastTouchX = (int) (e.getX() + 0.5f); mInitialTouchY = mLastTouchY = (int) (e.getY() + 0.5f); int nestedScrollAxis = ViewCompat.SCROLL_AXIS_NONE; if (canScrollHorizontally) { nestedScrollAxis |= ViewCompat.SCROLL_AXIS_HORIZONTAL; } if (canScrollVertically) { nestedScrollAxis |= ViewCompat.SCROLL_AXIS_VERTICAL; } startNestedScroll(nestedScrollAxis); } break; case MotionEventCompat.ACTION_POINTER_DOWN: { mScrollPointerId = MotionEventCompat.getPointerId(e, actionIndex); mInitialTouchX = mLastTouchX = (int) (MotionEventCompat.getX(e, actionIndex) + 0.5f); mInitialTouchY = mLastTouchY = (int) (MotionEventCompat.getY(e, actionIndex) + 0.5f); } break; case MotionEvent.ACTION_MOVE: { final int index = MotionEventCompat.findPointerIndex(e, mScrollPointerId); if (index < 0) { Log.e( TAG, "Error processing scroll; pointer index for id " + mScrollPointerId + " not found. Did any MotionEvents get skipped?"); return false; } final int x = (int) (MotionEventCompat.getX(e, index) + 0.5f); final int y = (int) (MotionEventCompat.getY(e, index) + 0.5f); int dx = mLastTouchX - x; int dy = mLastTouchY - y; if (dispatchNestedPreScroll(dx, dy, mScrollConsumed, mScrollOffset)) { dx -= mScrollConsumed[0]; dy -= mScrollConsumed[1]; vtev.offsetLocation(mScrollOffset[0], mScrollOffset[1]); // Updated the nested offsets mNestedOffsets[0] += mScrollOffset[0]; mNestedOffsets[1] += mScrollOffset[1]; } if (mScrollState != SCROLL_STATE_DRAGGING) { boolean startScroll = false; if (canScrollHorizontally && Math.abs(dx) > mTouchSlop) { if (dx > 0) { dx -= mTouchSlop; } else { dx += mTouchSlop; } startScroll = true; } if (canScrollVertically && Math.abs(dy) > mTouchSlop) { if (dy > 0) { dy -= mTouchSlop; } else { dy += mTouchSlop; } startScroll = true; } if (startScroll) { setScrollState(SCROLL_STATE_DRAGGING); } } if (mScrollState == SCROLL_STATE_DRAGGING) { mLastTouchX = x - mScrollOffset[0]; mLastTouchY = y - mScrollOffset[1]; if (scrollByInternal( canScrollHorizontally ? dx : 0, canScrollVertically ? dy : 0, vtev)) { getParent().requestDisallowInterceptTouchEvent(true); } } } break; case MotionEventCompat.ACTION_POINTER_UP: { onPointerUp(e); } break; case MotionEvent.ACTION_UP: { mVelocityTracker.addMovement(vtev); eventAddedToVelocityTracker = true; mVelocityTracker.computeCurrentVelocity(1000, mMaxFlingVelocity); final float xvel = canScrollHorizontally ? -VelocityTrackerCompat.getXVelocity(mVelocityTracker, mScrollPointerId) : 0; final float yvel = canScrollVertically ? -VelocityTrackerCompat.getYVelocity(mVelocityTracker, mScrollPointerId) : 0; if (!((xvel != 0 || yvel != 0) && fling((int) xvel, (int) yvel))) { setScrollState(SCROLL_STATE_IDLE); } resetTouch(); } break; case MotionEvent.ACTION_CANCEL: { cancelTouch(); } break; } if (!eventAddedToVelocityTracker) { mVelocityTracker.addMovement(vtev); } vtev.recycle(); return true; }
public boolean onTouchEvent(MotionEvent ev) { int action = MotionEventCompat.getActionMasked(ev); if ((this.mReturningToStart) && (action == 0)) { this.mReturningToStart = false; } if ((!isEnabled()) || (this.mReturningToStart) || (canChildScrollUp())) { return false; } switch (action) { case 0: this.mActivePointerId = MotionEventCompat.getPointerId(ev, 0); this.mIsBeingDragged = false; break; case 2: int pointerIndex = MotionEventCompat.findPointerIndex(ev, this.mActivePointerId); if (pointerIndex < 0) { Log.e(LOG_TAG, "Got ACTION_MOVE event but have an invalid active pointer id."); return false; } float y = MotionEventCompat.getY(ev, pointerIndex); float overscrollTop = (y - this.mInitialMotionY) * 0.5F; if (this.mIsBeingDragged) { this.mProgress.showArrow(true); float originalDragPercent = overscrollTop / this.mTotalDragDistance; if (originalDragPercent < 0.0F) { return false; } float dragPercent = Math.min(1.0F, Math.abs(originalDragPercent)); float adjustedPercent = (float) Math.max(dragPercent - 0.4D, 0.0D) * 5.0F / 3.0F; float extraOS = Math.abs(overscrollTop) - this.mTotalDragDistance; float slingshotDist = this.mUsingCustomStart ? this.mSpinnerFinalOffset - this.mOriginalOffsetTop : this.mSpinnerFinalOffset; float tensionSlingshotPercent = Math.max(0.0F, Math.min(extraOS, slingshotDist * 2.0F) / slingshotDist); float tensionPercent = (float) (tensionSlingshotPercent / 4.0F - Math.pow(tensionSlingshotPercent / 4.0F, 2.0D)) * 2.0F; float extraMove = slingshotDist * tensionPercent * 2.0F; int targetY = this.mOriginalOffsetTop + (int) (slingshotDist * dragPercent + extraMove); if (this.mCircleView.getVisibility() != 0) { this.mCircleView.setVisibility(0); } if (!this.mScale) { ViewCompat.setScaleX(this.mCircleView, 1.0F); ViewCompat.setScaleY(this.mCircleView, 1.0F); } if (overscrollTop < this.mTotalDragDistance) { if (this.mScale) { setAnimationProgress(overscrollTop / this.mTotalDragDistance); } if ((this.mProgress.getAlpha() > 76) && (!isAnimationRunning(this.mAlphaStartAnimation))) { startProgressAlphaStartAnimation(); } float strokeStart = adjustedPercent * 0.8F; this.mProgress.setStartEndTrim(0.0F, Math.min(0.8F, strokeStart)); this.mProgress.setArrowScale(Math.min(1.0F, adjustedPercent)); } else if ((this.mProgress.getAlpha() < 255) && (!isAnimationRunning(this.mAlphaMaxAnimation))) { startProgressAlphaMaxAnimation(); } float rotation = (-0.25F + 0.4F * adjustedPercent + tensionPercent * 2.0F) * 0.5F; this.mProgress.setProgressRotation(rotation); setTargetOffsetTopAndBottom(targetY - this.mCurrentTargetOffsetTop, true); } break; case 5: int index = MotionEventCompat.getActionIndex(ev); this.mActivePointerId = MotionEventCompat.getPointerId(ev, index); break; case 6: onSecondaryPointerUp(ev); break; case 1: case 3: if (this.mActivePointerId == -1) { if (action == 1) { Log.e(LOG_TAG, "Got ACTION_UP event but don't have an active pointer id."); } return false; } int pointerIndex_1 = MotionEventCompat.findPointerIndex(ev, this.mActivePointerId); float y_1 = MotionEventCompat.getY(ev, pointerIndex_1); float overscrollTop_1 = (y_1 - this.mInitialMotionY) * 0.5F; this.mIsBeingDragged = false; if (overscrollTop_1 > this.mTotalDragDistance) { setRefreshing(true, true); } else { this.mRefreshing = false; this.mProgress.setStartEndTrim(0.0F, 0.0F); Animation.AnimationListener listener = null; if (!this.mScale) listener = new Animation.AnimationListener() { public void onAnimationStart(Animation animation) {} public void onAnimationEnd(Animation animation) { if (!MySwipeRefreshLayout.this.mScale) MySwipeRefreshLayout.this.startScaleDownAnimation(null); } public void onAnimationRepeat(Animation animation) {} }; animateOffsetToStartPosition(this.mCurrentTargetOffsetTop, listener); this.mProgress.showArrow(false); } this.mActivePointerId = -1; return false; case 4: } return true; }
@Override public boolean onInterceptTouchEvent(MotionEvent ev) { boolean handle = false; if (!mEnabled) { return false; } final int action = ev.getAction() & MotionEventCompat.ACTION_MASK; if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) { endDrag(); return false; } if (action != MotionEvent.ACTION_DOWN) { if (mIsDragging) { return true; } else if (mIsUnableToDrag) { return false; } } switch (action) { case MotionEvent.ACTION_MOVE: final int activePointerId = mActivePointerId; if (activePointerId == INVALID_POINTER) { break; } final int pointerIndex = MotionEventCompat.findPointerIndex(ev, activePointerId); if (pointerIndex == -1) { mActivePointerId = INVALID_POINTER; break; } final float x = MotionEventCompat.getX(ev, pointerIndex); final float dx = x - mLastX; final float xDiff = Math.abs(dx); final float y = MotionEventCompat.getY(ev, pointerIndex); final float dy = y - mLastY; final float yDiff = Math.abs(y - mLastY); if (xDiff > mTouchSlop && xDiff > yDiff && allowDragingX(dx, mInitialX)) { handle = true; mLastX = x; } else if (yDiff > mTouchSlop && yDiff > xDiff && allowDragingY(dy, mInitialY)) { handle = true; mLastY = y; } break; case MotionEvent.ACTION_DOWN: mActivePointerId = ev.getAction() & (Build.VERSION.SDK_INT >= 8 ? MotionEvent.ACTION_POINTER_INDEX_MASK : MotionEventCompat.ACTION_POINTER_INDEX_MASK); mLastX = mInitialX = MotionEventCompat.getX(ev, mActivePointerId); mLastY = mInitialY = MotionEventCompat.getY(ev, mActivePointerId); if (allowSlidingFromHereX(ev, mInitialX)) { handle = false; // If nobody else got the focus we use it to close the layer return super.onInterceptTouchEvent(ev); } else if (allowSlidingFromHereY(ev, mInitialY)) { handle = false; // If nobody else got the focus we use it to close the layer return super.onInterceptTouchEvent(ev); } else { mIsUnableToDrag = true; } break; case MotionEventCompat.ACTION_POINTER_UP: onSecondaryPointerUp(ev); break; } if (!mIsDragging) { if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMovement(ev); } return handle; }
@Override public boolean onTouchEvent(MotionEvent ev) { if (!mEnabled) return false; // if (!mIsBeingDragged && !thisTouchAllowed(ev)) // return false; if (!mIsBeingDragged && !mQuickReturn) return false; final int action = ev.getAction(); if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMovement(ev); switch (action & MotionEventCompat.ACTION_MASK) { case MotionEvent.ACTION_DOWN: /* * If being flinged and user touches, stop the fling. isFinished * will be false if being flinged. */ completeScroll(); // Remember where the motion event started mLastMotionX = mInitialMotionX = ev.getX(); mActivePointerId = MotionEventCompat.getPointerId(ev, 0); break; case MotionEvent.ACTION_MOVE: if (!mIsBeingDragged) { if (mActivePointerId == INVALID_POINTER) break; final int pointerIndex = getPointerIndex(ev, mActivePointerId); final float x = MotionEventCompat.getX(ev, pointerIndex); final float dx = x - mLastMotionX; final float xDiff = Math.abs(dx); final float y = MotionEventCompat.getY(ev, pointerIndex); final float yDiff = Math.abs(y - mLastMotionY); if (DEBUG) Log.v( TAG, "onTouch moved to:(" + x + ", " + y + "), diff:(" + xDiff + ", " + yDiff + ")\nmIsBeingDragged:" + mIsBeingDragged + ", mLastMotionX:" + mLastMotionX); if ((xDiff > mTouchSlop || (mQuickReturn && xDiff > mTouchSlop / 4)) && xDiff > yDiff && thisSlideAllowed(dx)) { if (DEBUG) Log.v(TAG, "Starting drag! from onTouch"); startDrag(); mLastMotionX = x; setScrollingCacheEnabled(true); } else { if (DEBUG) Log.v(TAG, "onTouch returning false"); return false; } } if (mIsBeingDragged) { // Scroll to follow the motion event final int activePointerIndex = getPointerIndex(ev, mActivePointerId); if (mActivePointerId == INVALID_POINTER) { break; } final float x = MotionEventCompat.getX(ev, activePointerIndex); final float deltaX = mLastMotionX - x; mLastMotionX = x; float oldScrollX = getScrollX(); float scrollX = oldScrollX + deltaX; final float leftBound = getLeftBound(); final float rightBound = getRightBound(); if (scrollX < leftBound) { scrollX = leftBound; } else if (scrollX > rightBound) { scrollX = rightBound; } // Don't lose the rounded component mLastMotionX += scrollX - (int) scrollX; scrollTo((int) scrollX, getScrollY()); pageScrolled((int) scrollX); } break; case MotionEvent.ACTION_UP: if (mIsBeingDragged) { final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); int initialVelocity = (int) VelocityTrackerCompat.getXVelocity(velocityTracker, mActivePointerId); final int scrollX = getScrollX(); // final int widthWithMargin = getWidth(); // final float pageOffset = (float) (scrollX % widthWithMargin) / widthWithMargin; // TODO test this. should get better flinging behavior final float pageOffset = (float) (scrollX - getDestScrollX(mCurItem)) / getBehindWidth(); final int activePointerIndex = getPointerIndex(ev, mActivePointerId); if (mActivePointerId != INVALID_POINTER) { final float x = MotionEventCompat.getX(ev, activePointerIndex); final int totalDelta = (int) (x - mInitialMotionX); int nextPage = determineTargetPage(pageOffset, initialVelocity, totalDelta); setCurrentItemInternal(nextPage, true, true, initialVelocity); } else { setCurrentItemInternal(mCurItem, true, true, initialVelocity); } mActivePointerId = INVALID_POINTER; endDrag(); } else if (mQuickReturn && mViewBehind.menuTouchInQuickReturn(mContent, mCurItem, ev.getX() + mScrollX)) { // close the menu setCurrentItem(1); endDrag(); } break; case MotionEvent.ACTION_CANCEL: if (mIsBeingDragged) { setCurrentItemInternal(mCurItem, true, true); mActivePointerId = INVALID_POINTER; endDrag(); } break; case MotionEventCompat.ACTION_POINTER_DOWN: { final int index = MotionEventCompat.getActionIndex(ev); final float x = MotionEventCompat.getX(ev, index); mLastMotionX = x; mActivePointerId = MotionEventCompat.getPointerId(ev, index); break; } case MotionEventCompat.ACTION_POINTER_UP: onSecondaryPointerUp(ev); int pointerIndex = this.getPointerIndex(ev, mActivePointerId); if (mActivePointerId == INVALID_POINTER) break; mLastMotionX = MotionEventCompat.getX(ev, pointerIndex); break; } return true; }
@Override public boolean onTouchEvent(MotionEvent ev) { if (!mIsBeingDragged) { return super.onTouchEvent(ev); } final int action = MotionEventCompat.getActionMasked(ev); switch (action) { case MotionEvent.ACTION_MOVE: { final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); if (pointerIndex < 0) { return false; } final float y = MotionEventCompat.getY(ev, pointerIndex); // final float yDiff = Math.abs(y - mInitialMotionY); final float yDiff = y - mInitialMotionY; final float scrollTop = yDiff * DRAG_RATE; float originalDragPercent = scrollTop / mTotalDragDistance; if (originalDragPercent < 0) { return false; } float dragPercent = Math.min(1f, Math.abs(originalDragPercent)); // float adjustedPercent = (float) Math.max(dragPercent - .4, 0) * 5 / 3; // float adjustedPercent = dragPercent; float extraOS = Math.abs(scrollTop) - mTotalDragDistance; float slingshotDist = mSpinnerFinalOffset; float tensionSlingshotPercent = Math.max(0, Math.min(extraOS, slingshotDist * 2) / slingshotDist); float tensionPercent = (float) ((tensionSlingshotPercent / 4) - Math.pow((tensionSlingshotPercent / 4), 2)) * 2f; float extraMove = (slingshotDist) * tensionPercent * 2; int targetY = (int) ((slingshotDist * dragPercent) + extraMove); if (mRefreshView.getVisibility() != View.VISIBLE) { mRefreshView.setVisibility(View.VISIBLE); } if (scrollTop < mTotalDragDistance) { mRefreshDrawable.setPercent(dragPercent); } setTargetOffsetTop(targetY - mCurrentOffsetTop, true); break; } case MotionEventCompat.ACTION_POINTER_DOWN: final int index = MotionEventCompat.getActionIndex(ev); mActivePointerId = MotionEventCompat.getPointerId(ev, index); break; case MotionEventCompat.ACTION_POINTER_UP: onSecondaryPointerUp(ev); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: { if (mActivePointerId == INVALID_POINTER) { return false; } final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); final float y = MotionEventCompat.getY(ev, pointerIndex); final float overscrollTop = (y - mInitialMotionY) * DRAG_RATE; mIsBeingDragged = false; if (overscrollTop > mTotalDragDistance) { setRefreshing(true, true); } else { mRefreshing = false; animateOffsetToStartPosition(); } mActivePointerId = INVALID_POINTER; return false; } } return true; }