List of usage examples for android.view VelocityTracker computeCurrentVelocity
public void computeCurrentVelocity(int units, float maxVelocity)
From source file:dev.dworks.libs.widget.ViewPager.java
@Override public boolean onTouchEvent(MotionEvent ev) { if (mFakeDragging) { // A fake drag is in progress already, ignore this real one // but still eat the touch events. // (It is likely that the user is multi-touching the screen.) return true; }/*from ww w . ja v a 2 s. c o m*/ if (ev.getAction() == MotionEvent.ACTION_DOWN && ev.getEdgeFlags() != 0) { // Don't handle edge touches immediately -- they may actually belong to one of our // descendants. return false; } if (mAdapter == null || mAdapter.getCount() == 0) { // Nothing to present or scroll; nothing to touch. return false; } if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMovement(ev); final int action = ev.getAction(); boolean needsInvalidate = false; switch (action & MotionEventCompat.ACTION_MASK) { case MotionEvent.ACTION_DOWN: { mScroller.abortAnimation(); mPopulatePending = false; populate(); mIsBeingDragged = true; setScrollState(SCROLL_STATE_DRAGGING); // Remember where the motion event started mLastMotionX = mInitialMotionX = ev.getX(); mLastMotionY = mInitialMotionY = ev.getY(); mActivePointerId = MotionEventCompat.getPointerId(ev, 0); break; } case MotionEvent.ACTION_MOVE: if (!mIsBeingDragged) { final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); final float x = MotionEventCompat.getX(ev, pointerIndex); final float xDiff = Math.abs(x - mLastMotionX); final float y = MotionEventCompat.getY(ev, pointerIndex); final float yDiff = Math.abs(y - mLastMotionY); float primaryDiff; float secondaryDiff; if (mOrientation == HORIZONTAL) { primaryDiff = xDiff; secondaryDiff = yDiff; } else { primaryDiff = yDiff; secondaryDiff = xDiff; } if (DEBUG) Log.v(TAG, "Moved x to " + x + "," + y + " diff=" + xDiff + "," + yDiff); if (primaryDiff > mTouchSlop && primaryDiff > secondaryDiff) { if (DEBUG) Log.v(TAG, "Starting drag!"); mIsBeingDragged = true; if (mOrientation == HORIZONTAL) { mLastMotionX = x; } else { mLastMotionY = y; } setScrollState(SCROLL_STATE_DRAGGING); setScrollingCacheEnabled(true); } } // Not else! Note that mIsBeingDragged can be set above. if (mIsBeingDragged) { // Scroll to follow the motion event final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); if (mOrientation == HORIZONTAL) { final float x = MotionEventCompat.getX(ev, activePointerIndex); needsInvalidate |= performDragX(x); } else { final float y = MotionEventCompat.getY(ev, activePointerIndex); needsInvalidate |= performDragY(y); } } break; case MotionEvent.ACTION_UP: if (mIsBeingDragged) { final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); int initialVelocity; mPopulatePending = true; final ItemInfo ii = infoForCurrentScrollPosition(); final int currentPage = ii.position; final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); final float pageOffset; final int totalDelta; if (mOrientation == HORIZONTAL) { initialVelocity = (int) VelocityTrackerCompat.getXVelocity(velocityTracker, mActivePointerId); final int width = getClientWidth(); final int scrollX = getScrollX(); pageOffset = (((float) scrollX / width) - ii.offset) / ii.widthFactor; final float x = MotionEventCompat.getX(ev, activePointerIndex); totalDelta = (int) (x - mInitialMotionX); } else { initialVelocity = (int) VelocityTrackerCompat.getYVelocity(velocityTracker, mActivePointerId); final int height = getHeight(); final int scrollY = getScrollY(); pageOffset = (((float) scrollY / height) - ii.offset) / ii.heightFactor; final float y = MotionEventCompat.getY(ev, activePointerIndex); totalDelta = (int) (y - mInitialMotionY); } int nextPage = determineTargetPage(currentPage, pageOffset, initialVelocity, totalDelta); setCurrentItemInternal(nextPage, true, true, initialVelocity); mActivePointerId = INVALID_POINTER; endDrag(); if (mOrientation == HORIZONTAL) { needsInvalidate = mLeftEdge.onRelease() | mRightEdge.onRelease(); } else { needsInvalidate = mTopEdge.onRelease() | mBottomEdge.onRelease(); } } break; case MotionEvent.ACTION_CANCEL: if (mIsBeingDragged) { scrollToItem(mCurItem, true, 0, false); mActivePointerId = INVALID_POINTER; endDrag(); if (mOrientation == HORIZONTAL) { needsInvalidate = mLeftEdge.onRelease() | mRightEdge.onRelease(); } else { needsInvalidate = mTopEdge.onRelease() | mBottomEdge.onRelease(); } } break; case MotionEventCompat.ACTION_POINTER_DOWN: { final int index = MotionEventCompat.getActionIndex(ev); if (mOrientation == HORIZONTAL) { final float x = MotionEventCompat.getX(ev, index); mLastMotionX = x; } else { final float y = MotionEventCompat.getY(ev, index); mLastMotionY = y; } mActivePointerId = MotionEventCompat.getPointerId(ev, index); break; } case MotionEventCompat.ACTION_POINTER_UP: onSecondaryPointerUp(ev); if (mOrientation == HORIZONTAL) { mLastMotionX = MotionEventCompat.getX(ev, MotionEventCompat.findPointerIndex(ev, mActivePointerId)); } else { mLastMotionY = MotionEventCompat.getY(ev, MotionEventCompat.findPointerIndex(ev, mActivePointerId)); } break; } if (needsInvalidate) { ViewCompat.postInvalidateOnAnimation(this); } return true; }
From source file:com.wb.launcher3.Page.java
@Override public boolean onTouchEvent(MotionEvent ev) { if (DISABLE_TOUCH_INTERACTION) { return false; }//from w ww .j a v a 2 s . c om super.onTouchEvent(ev); // Skip touch handling if there are no pages to swipe if (getChildCount() <= 0) return super.onTouchEvent(ev); acquireVelocityTrackerAndAddMovement(ev); final int action = ev.getAction(); switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: /* * If being flinged and user touches, stop the fling. isFinished * will be false if being flinged. */ if (!mScroller.isFinished()) { mScroller.abortAnimation(); } // Remember where the motion event started mDownMotionX = mLastMotionX = ev.getX(); mDownMotionY = mLastMotionY = ev.getY(); mDownScrollX = getScrollX(); float[] p = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY); mParentDownMotionX = p[0]; mParentDownMotionY = p[1]; mLastMotionXRemainder = 0; mTotalMotionX = 0; mActivePointerId = ev.getPointerId(0); if (mTouchState == TOUCH_STATE_SCROLLING) { pageBeginMoving(); } break; case MotionEvent.ACTION_MOVE: //*/zhangwuba add 2014-5-8 if (getLauncherDeleteAppSate()) { return true; } //*/ if (mTouchState == TOUCH_STATE_SCROLLING) { // Scroll to follow the motion event final int pointerIndex = ev.findPointerIndex(mActivePointerId); if (pointerIndex == -1) return true; final float x = ev.getX(pointerIndex); final float deltaX = mLastMotionX + mLastMotionXRemainder - x; mTotalMotionX += Math.abs(deltaX); // Only scroll and update mLastMotionX if we have moved some discrete amount. We // keep the remainder because we are actually testing if we've moved from the last // scrolled position (which is discrete). if (Math.abs(deltaX) >= 1.0f) { mTouchX += deltaX; mSmoothingTime = System.nanoTime() / NANOTIME_DIV; if (!mDeferScrollUpdate) { scrollBy((int) deltaX, 0); if (DEBUG) Log.d(TAG, "onTouchEvent().Scrolling: " + deltaX); } else { invalidate(); } mLastMotionX = x; mLastMotionXRemainder = deltaX - (int) deltaX; } else { awakenScrollBars(); } } else if (mTouchState == TOUCH_STATE_REORDERING) { // Update the last motion position mLastMotionX = ev.getX(); mLastMotionY = ev.getY(); // Update the parent down so that our zoom animations take this new movement into // account float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY); mParentDownMotionX = pt[0]; mParentDownMotionY = pt[1]; updateDragViewTranslationDuringDrag(); // Find the closest page to the touch point final int dragViewIndex = indexOfChild(mDragView); // Change the drag view if we are hovering over the drop target boolean isHoveringOverDelete = isHoveringOverDeleteDropTarget((int) mParentDownMotionX, (int) mParentDownMotionY); setPageHoveringOverDeleteDropTarget(dragViewIndex, isHoveringOverDelete); if (DEBUG) Log.d(TAG, "mLastMotionX: " + mLastMotionX); if (DEBUG) Log.d(TAG, "mLastMotionY: " + mLastMotionY); if (DEBUG) Log.d(TAG, "mParentDownMotionX: " + mParentDownMotionX); if (DEBUG) Log.d(TAG, "mParentDownMotionY: " + mParentDownMotionY); final int pageUnderPointIndex = getNearestHoverOverPageIndex(); if (pageUnderPointIndex > -1 && pageUnderPointIndex != indexOfChild(mDragView) && !isHoveringOverDelete) { mTempVisiblePagesRange[0] = 0; mTempVisiblePagesRange[1] = getPageCount() - 1; getOverviewModePages(mTempVisiblePagesRange); if (mTempVisiblePagesRange[0] <= pageUnderPointIndex && pageUnderPointIndex <= mTempVisiblePagesRange[1] && pageUnderPointIndex != mSidePageHoverIndex && mScroller.isFinished()) { mSidePageHoverIndex = pageUnderPointIndex; mSidePageHoverRunnable = new Runnable() { @Override public void run() { // Setup the scroll to the correct page before we swap the views snapToPage(pageUnderPointIndex); // For each of the pages between the paged view and the drag view, // animate them from the previous position to the new position in // the layout (as a result of the drag view moving in the layout) int shiftDelta = (dragViewIndex < pageUnderPointIndex) ? -1 : 1; int lowerIndex = (dragViewIndex < pageUnderPointIndex) ? dragViewIndex + 1 : pageUnderPointIndex; int upperIndex = (dragViewIndex > pageUnderPointIndex) ? dragViewIndex - 1 : pageUnderPointIndex; for (int i = lowerIndex; i <= upperIndex; ++i) { View v = getChildAt(i); // dragViewIndex < pageUnderPointIndex, so after we remove the // drag view all subsequent views to pageUnderPointIndex will // shift down. int oldX = getViewportOffsetX() + getChildOffset(i); int newX = getViewportOffsetX() + getChildOffset(i + shiftDelta); // Animate the view translation from its old position to its new // position AnimatorSet anim = (AnimatorSet) v.getTag(ANIM_TAG_KEY); if (anim != null) { anim.cancel(); } v.setTranslationX(oldX - newX); anim = new AnimatorSet(); anim.setDuration(REORDERING_REORDER_REPOSITION_DURATION); anim.playTogether(ObjectAnimator.ofFloat(v, "translationX", 0f)); anim.start(); v.setTag(anim); } removeView(mDragView); onRemoveView(mDragView, false); addView(mDragView, pageUnderPointIndex); onAddView(mDragView, pageUnderPointIndex); mSidePageHoverIndex = -1; mPageIndicator.setActiveMarker(getNextPage()); } }; postDelayed(mSidePageHoverRunnable, REORDERING_SIDE_PAGE_HOVER_TIMEOUT); } } else { removeCallbacks(mSidePageHoverRunnable); mSidePageHoverIndex = -1; } } else { determineScrollingStart(ev); } break; case MotionEvent.ACTION_UP: if (mTouchState == TOUCH_STATE_SCROLLING) { final int activePointerId = mActivePointerId; final int pointerIndex = ev.findPointerIndex(activePointerId); final float x = ev.getX(pointerIndex); final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); int velocityX = (int) velocityTracker.getXVelocity(activePointerId); final int deltaX = (int) (x - mDownMotionX); final int pageWidth = getPageAt(mCurrentPage).getMeasuredWidth(); boolean isSignificantMove = Math.abs(deltaX) > pageWidth * SIGNIFICANT_MOVE_THRESHOLD; mTotalMotionX += Math.abs(mLastMotionX + mLastMotionXRemainder - x); boolean isFling = mTotalMotionX > MIN_LENGTH_FOR_FLING && Math.abs(velocityX) > mFlingThresholdVelocity; if (!mFreeScroll) { // In the case that the page is moved far to one direction and then is flung // in the opposite direction, we use a threshold to determine whether we should // just return to the starting page, or if we should skip one further. boolean returnToOriginalPage = false; if (Math.abs(deltaX) > pageWidth * RETURN_TO_ORIGINAL_PAGE_THRESHOLD && Math.signum(velocityX) != Math.signum(deltaX) && isFling) { returnToOriginalPage = true; } //*/Added by tyd Greg 2014-03-20,for transition effect if (TydtechConfig.CYCLE_ROLL_PAGES_ENABLED) { m_moveNextDeltaX = deltaX; m_isSignificantMoveNext = (!returnToOriginalPage && (isSignificantMove || isFling)); } //*/ int finalPage; // We give flings precedence over large moves, which is why we short-circuit our // test for a large move if a fling has been registered. That is, a large // move to the left and fling to the right will register as a fling to the right. final boolean isRtl = isLayoutRtl(); boolean isDeltaXLeft = isRtl ? deltaX > 0 : deltaX < 0; boolean isVelocityXLeft = isRtl ? velocityX > 0 : velocityX < 0; if (((isSignificantMove && !isDeltaXLeft && !isFling) || (isFling && !isVelocityXLeft)) && mCurrentPage > 0) { finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1; snapToPageWithVelocity(finalPage, velocityX); } else if (((isSignificantMove && isDeltaXLeft && !isFling) || (isFling && isVelocityXLeft)) && mCurrentPage < getChildCount() - 1) { finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage + 1; snapToPageWithVelocity(finalPage, velocityX); } else { snapToDestination(); } } else if (mTouchState == TOUCH_STATE_PREV_PAGE) { // at this point we have not moved beyond the touch slop // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so // we can just page int nextPage = Math.max(0, mCurrentPage - 1); if (nextPage != mCurrentPage) { snapToPage(nextPage); } else { snapToDestination(); } } else { if (!mScroller.isFinished()) { mScroller.abortAnimation(); } float scaleX = getScaleX(); int vX = (int) (-velocityX * scaleX); int initialScrollX = (int) (getScrollX() * scaleX); mScroller.fling(initialScrollX, getScrollY(), vX, 0, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0); invalidate(); } } else if (mTouchState == TOUCH_STATE_NEXT_PAGE) { // at this point we have not moved beyond the touch slop // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so // we can just page int nextPage = Math.min(getChildCount() - 1, mCurrentPage + 1); if (nextPage != mCurrentPage) { snapToPage(nextPage); } else { snapToDestination(); } } else if (mTouchState == TOUCH_STATE_REORDERING) { // Update the last motion position mLastMotionX = ev.getX(); mLastMotionY = ev.getY(); // Update the parent down so that our zoom animations take this new movement into // account float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY); mParentDownMotionX = pt[0]; mParentDownMotionY = pt[1]; updateDragViewTranslationDuringDrag(); boolean handledFling = false; if (!DISABLE_FLING_TO_DELETE) { // Check the velocity and see if we are flinging-to-delete PointF flingToDeleteVector = isFlingingToDelete(); if (flingToDeleteVector != null) { onFlingToDelete(flingToDeleteVector); handledFling = true; } } if (!handledFling && isHoveringOverDeleteDropTarget((int) mParentDownMotionX, (int) mParentDownMotionY)) { onDropToDelete(); } } //*/Added by tyd Greg 2014-03-21,for support the touch swipe gesture else if (mTouchState == TOUCH_SWIPE_DOWN_GESTURE) { if (mOnTouchSwipeGestureListener != null) { mOnTouchSwipeGestureListener.fireSwipeDownAction(); } } else if (mTouchState == TOUCH_SWIPE_UP_GESTURE) { if (mOnTouchSwipeGestureListener != null) { mOnTouchSwipeGestureListener.fireSwipeUpAction(); } } //*/ else { if (!mCancelTap) { onUnhandledTap(ev); } } // Remove the callback to wait for the side page hover timeout removeCallbacks(mSidePageHoverRunnable); // End any intermediate reordering states resetTouchState(); break; case MotionEvent.ACTION_CANCEL: if (mTouchState == TOUCH_STATE_SCROLLING) { snapToDestination(); } resetTouchState(); break; case MotionEvent.ACTION_POINTER_UP: onSecondaryPointerUp(ev); releaseVelocityTracker(); break; } return true; }
From source file:com.bulletnoid.android.widget.StaggeredGridView.StaggeredGridView2.java
private void onTouchUp(MotionEvent ev) { switch (mTouchMode) { case TOUCH_MODE_DOWN: case TOUCH_MODE_TAP: case TOUCH_MODE_DONE_WAITING: final int motionPosition = mMotionPosition; final View child = getChildAt(motionPosition - mFirstPosition); if (child != null) { if (mTouchMode != TOUCH_MODE_DOWN) { child.setPressed(false); }/*from w w w. j a va 2 s .c o m*/ final float x = ev.getX(); final boolean inList = x > getPaddingLeft() /*mListPadding.left*/ && x < getWidth() - getPaddingRight()/*mListPadding.right*/; if (inList && !child.hasFocusable()) { if (mPerformClick == null) { mPerformClick = new PerformClick(); } final PerformClick performClick = mPerformClick; performClick.mClickMotionPosition = motionPosition; performClick.rememberWindowAttachCount(); //mResurrectToPosition = motionPosition; Log.d(TAG, "up:" + mTouchMode + ""); if (mTouchMode == TOUCH_MODE_DOWN || mTouchMode == TOUCH_MODE_TAP) { removeCallbacks( mTouchMode == TOUCH_MODE_DOWN ? mPendingCheckForTap : mPendingCheckForLongPress); //mLayoutMode = LAYOUT_NORMAL; if (!mDataChanged && mAdapter.isEnabled(motionPosition)) { mTouchMode = TOUCH_MODE_TAP; //setSelectedPositionInt(mMotionPosition); layoutChildren(mDataChanged); child.setPressed(true); positionSelector(mMotionPosition, child); setPressed(true); if (mSelector != null) { Drawable d = mSelector.getCurrent(); if (d != null && d instanceof TransitionDrawable) { ((TransitionDrawable) d).resetTransition(); } } if (mTouchModeReset != null) { removeCallbacks(mTouchModeReset); } mTouchModeReset = new Runnable() { @Override public void run() { mTouchModeReset = null; mTouchMode = TOUCH_MODE_REST; child.setPressed(false); setPressed(false); if (!mDataChanged /*&& isAttachedToWindow()*/) { performClick.run(); } } }; postDelayed(mTouchModeReset, ViewConfiguration.getPressedStateDuration()); } else { mTouchMode = TOUCH_MODE_REST; updateSelectorState(); } return; } else if (!mDataChanged && mAdapter.isEnabled(motionPosition)) { performClick.run(); } } } mTouchMode = TOUCH_MODE_REST; updateSelectorState(); break; case TOUCH_MODE_DRAGGING: final int childCount = getChildCount(); if (childCount > 0) { final int firstChildTop = getChildAt(0).getTop(); final int lastChildBottom = getChildAt(childCount - 1).getBottom(); final int contentTop = getPaddingTop();//mListPadding.top; final int contentBottom = getHeight() - getPaddingBottom();//mListPadding.bottom; if (mFirstPosition == 0 && firstChildTop >= contentTop && mFirstPosition + childCount < mItemCount && lastChildBottom <= getHeight() - contentBottom) { mTouchMode = TOUCH_MODE_REST; reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); } else { final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); final int initialVelocity = (int) (velocityTracker.getYVelocity(mActivePointerId) * mVelocityScale); // Fling if we have enough velocity and we aren't at a boundary. // Since we can potentially overfling more than we can overscroll, don't // allow the weird behavior where you can scroll to a boundary then // fling further. if (Math.abs(initialVelocity) > mMinimumVelocity && !((mFirstPosition == 0 && firstChildTop == contentTop - mOverscrollDistance) || (mFirstPosition + childCount == mItemCount && lastChildBottom == contentBottom + mOverscrollDistance))) { if (mFlingRunnable == null) { mFlingRunnable = new FlingRunnable(); } reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING); mFlingRunnable.start(-initialVelocity); } else { mTouchMode = TOUCH_MODE_REST; reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); if (mFlingRunnable != null) { mFlingRunnable.endFling(); } /*if (mPositionScroller != null) { mPositionScroller.stop(); }*/ } } } else { mTouchMode = TOUCH_MODE_REST; reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); } break; case TOUCH_MODE_OVERSCROLL: if (mFlingRunnable == null) { mFlingRunnable = new FlingRunnable(); } final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); final int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId); reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING); if (Math.abs(initialVelocity) > mMinimumVelocity) { mFlingRunnable.startOverfling(-initialVelocity); } else { mFlingRunnable.startSpringback(); } break; } setPressed(false); /*if (mEdgeGlowTop != null) { mEdgeGlowTop.onRelease(); mEdgeGlowBottom.onRelease(); }*/ // Need to redraw since we probably aren't drawing the selector anymore invalidate(); removeCallbacks(mPendingCheckForLongPress); recycleVelocityTracker(); mActivePointerId = INVALID_POINTER; /*if (PROFILE_SCROLLING) { if (mScrollProfilingStarted) { Debug.stopMethodTracing(); mScrollProfilingStarted = false; } } if (mScrollStrictSpan != null) { mScrollStrictSpan.finish(); mScrollStrictSpan = null; }*/ }
From source file:com.glview.widget.AbsListView.java
private void onTouchUp(MotionEvent ev) { switch (mTouchMode) { case TOUCH_MODE_DOWN: case TOUCH_MODE_TAP: case TOUCH_MODE_DONE_WAITING: final int motionPosition = mMotionPosition; final View child = getChildAt(motionPosition - mFirstPosition); if (child != null) { if (mTouchMode != TOUCH_MODE_DOWN) { child.setPressed(false); }/* w w w. j a v a 2 s . c o m*/ final float x = ev.getX(); final boolean inList = x > mListPadding.left && x < getWidth() - mListPadding.right; if (inList && !child.hasFocusable()) { if (mPerformClick == null) { mPerformClick = new PerformClick(); } final AbsListView.PerformClick performClick = mPerformClick; performClick.mClickMotionPosition = motionPosition; performClick.rememberWindowAttachCount(); mResurrectToPosition = motionPosition; if (mTouchMode == TOUCH_MODE_DOWN || mTouchMode == TOUCH_MODE_TAP) { removeCallbacks( mTouchMode == TOUCH_MODE_DOWN ? mPendingCheckForTap : mPendingCheckForLongPress); mLayoutMode = LAYOUT_NORMAL; if (!mDataChanged && mAdapter.isEnabled(motionPosition)) { mTouchMode = TOUCH_MODE_TAP; setSelectedPositionInt(mMotionPosition); layoutChildren(); child.setPressed(true); positionSelector(mMotionPosition, child); setPressed(true); if (mSelector != null) { Drawable d = mSelector.getCurrent(); if (d != null && d instanceof TransitionDrawable) { ((TransitionDrawable) d).resetTransition(); } mSelector.setHotspot(x, ev.getY()); } if (mTouchModeReset != null) { removeCallbacks(mTouchModeReset); } mTouchModeReset = new Runnable() { @Override public void run() { mTouchModeReset = null; mTouchMode = TOUCH_MODE_REST; child.setPressed(false); setPressed(false); if (!mDataChanged && !mIsDetaching && isAttachedToWindow()) { performClick.run(); } } }; postDelayed(mTouchModeReset, ViewConfiguration.getPressedStateDuration()); } else { mTouchMode = TOUCH_MODE_REST; updateSelectorState(); } return; } else if (!mDataChanged && mAdapter.isEnabled(motionPosition)) { performClick.run(); } } } mTouchMode = TOUCH_MODE_REST; updateSelectorState(); break; case TOUCH_MODE_SCROLL: final int childCount = getChildCount(); if (childCount > 0) { final int firstChildTop = getChildAt(0).getTop(); final int lastChildBottom = getChildAt(childCount - 1).getBottom(); final int contentTop = mListPadding.top; final int contentBottom = getHeight() - mListPadding.bottom; if (mFirstPosition == 0 && firstChildTop >= contentTop && mFirstPosition + childCount < mItemCount && lastChildBottom <= getHeight() - contentBottom) { mTouchMode = TOUCH_MODE_REST; reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); } else { final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); final int initialVelocity = (int) (velocityTracker.getYVelocity(mActivePointerId) * mVelocityScale); // Fling if we have enough velocity and we aren't at a boundary. // Since we can potentially overfling more than we can overscroll, don't // allow the weird behavior where you can scroll to a boundary then // fling further. boolean flingVelocity = Math.abs(initialVelocity) > mMinimumVelocity; if (flingVelocity && !((mFirstPosition == 0 && firstChildTop == contentTop - mOverscrollDistance) || (mFirstPosition + childCount == mItemCount && lastChildBottom == contentBottom + mOverscrollDistance))) { if (!dispatchNestedPreFling(0, -initialVelocity)) { if (mFlingRunnable == null) { mFlingRunnable = new FlingRunnable(); } reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING); mFlingRunnable.start(-initialVelocity); dispatchNestedFling(0, -initialVelocity, true); } else { mTouchMode = TOUCH_MODE_REST; reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); } } else { mTouchMode = TOUCH_MODE_REST; reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); if (mFlingRunnable != null) { mFlingRunnable.endFling(); } if (mPositionScroller != null) { mPositionScroller.stop(); } if (flingVelocity && !dispatchNestedPreFling(0, -initialVelocity)) { dispatchNestedFling(0, -initialVelocity, false); } } } } else { mTouchMode = TOUCH_MODE_REST; reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); } break; case TOUCH_MODE_OVERSCROLL: if (mFlingRunnable == null) { mFlingRunnable = new FlingRunnable(); } final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); final int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId); reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING); if (Math.abs(initialVelocity) > mMinimumVelocity) { mFlingRunnable.startOverfling(-initialVelocity); } else { mFlingRunnable.startSpringback(); } break; } setPressed(false); if (mEdgeGlowTop != null) { mEdgeGlowTop.onRelease(); mEdgeGlowBottom.onRelease(); } // Need to redraw since we probably aren't drawing the selector anymore invalidate(); removeCallbacks(mPendingCheckForLongPress); recycleVelocityTracker(); mActivePointerId = INVALID_POINTER; if (PROFILE_SCROLLING) { if (mScrollProfilingStarted) { Debug.stopMethodTracing(); mScrollProfilingStarted = false; } } }
From source file:com.example.libwidgettv.bak.AbsListView.java
@Override public boolean onTouchEvent(MotionEvent ev) { if (!isEnabled()) { // A disabled view that is clickable still consumes the touch // events, it just doesn't respond to them. return isClickable() || isLongClickable(); }/*from w w w .ja v a 2 s . c o m*/ if (mFastScroller != null) { boolean intercepted = mFastScroller.onTouchEvent(ev); if (intercepted) { return true; } } final int action = ev.getAction(); View v; initVelocityTrackerIfNotExists(); mVelocityTracker.addMovement(ev); switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: { switch (mTouchMode) { case TOUCH_MODE_OVERFLING: { mFlingRunnable.endFling(); if (mPositionScroller != null) { mPositionScroller.stop(); } mTouchMode = TOUCH_MODE_OVERSCROLL; mMotionX = (int) ev.getX(); mMotionY = mLastY = (int) ev.getY(); mMotionCorrection = 0; mActivePointerId = ev.getPointerId(0); mDirection = 0; break; } default: { mActivePointerId = ev.getPointerId(0); final int x = (int) ev.getX(); final int y = (int) ev.getY(); int motionPosition = pointToPosition(x, y); if (!mDataChanged) { if ((mTouchMode != TOUCH_MODE_FLING) && (motionPosition >= 0) && (getAdapter().isEnabled(motionPosition))) { // User clicked on an actual view (and was not stopping // a fling). // It might be a click or a scroll. Assume it is a click // until // proven otherwise mTouchMode = TOUCH_MODE_DOWN; // FIXME Debounce if (mPendingCheckForTap == null) { mPendingCheckForTap = new CheckForTap(); } postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout()); } else { if (mTouchMode == TOUCH_MODE_FLING) { // Stopped a fling. It is a scroll. createScrollingCache(); mTouchMode = TOUCH_MODE_SCROLL; mMotionCorrection = 0; motionPosition = findMotionRow(y); mFlingRunnable.flywheelTouch(); } } } if (motionPosition >= 0) { // Remember where the motion event started v = getChildAt(motionPosition - mFirstPosition); mMotionViewOriginalTop = v.getTop(); } mMotionX = x; mMotionY = y; mMotionPosition = motionPosition; mLastY = Integer.MIN_VALUE; break; } } // if (performButtonActionOnTouchDown(ev)) { // if (mTouchMode == TOUCH_MODE_DOWN) { // removeCallbacks(mPendingCheckForTap); // } // } break; } case MotionEvent.ACTION_MOVE: { int pointerIndex = ev.findPointerIndex(mActivePointerId); if (pointerIndex == -1) { pointerIndex = 0; mActivePointerId = ev.getPointerId(pointerIndex); } final int y = (int) ev.getY(pointerIndex); switch (mTouchMode) { case TOUCH_MODE_DOWN: case TOUCH_MODE_TAP: case TOUCH_MODE_DONE_WAITING: // Check if we have moved far enough that it looks more like a // scroll than a tap startScrollIfNeeded(y); break; case TOUCH_MODE_SCROLL: case TOUCH_MODE_OVERSCROLL: scrollIfNeeded(y); break; } break; } case MotionEvent.ACTION_UP: { switch (mTouchMode) { case TOUCH_MODE_DOWN: case TOUCH_MODE_TAP: case TOUCH_MODE_DONE_WAITING: final int motionPosition = mMotionPosition; final View child = getChildAt(motionPosition - mFirstPosition); final float x = ev.getX(); final boolean inList = x > mListPadding.left && x < getWidth() - mListPadding.right; if (child != null && !child.hasFocusable() && inList) { if (mTouchMode != TOUCH_MODE_DOWN) { child.setPressed(false); } if (mPerformClick == null) { mPerformClick = new PerformClick(); } final AbsListView.PerformClick performClick = mPerformClick; performClick.mClickMotionPosition = motionPosition; performClick.rememberWindowAttachCount(); mResurrectToPosition = motionPosition; if (mTouchMode == TOUCH_MODE_DOWN || mTouchMode == TOUCH_MODE_TAP) { final Handler handler = getHandler(); if (handler != null) { handler.removeCallbacks(mTouchMode == TOUCH_MODE_DOWN ? mPendingCheckForTap : mPendingCheckForLongPress); } mLayoutMode = LAYOUT_NORMAL; if (!mDataChanged && mAdapter.isEnabled(motionPosition)) { mTouchMode = TOUCH_MODE_TAP; setSelectedPositionInt(mMotionPosition); layoutChildren(); child.setPressed(true); positionSelector(mMotionPosition, child); setPressed(true); if (mSelector != null) { Drawable d = mSelector.getCurrent(); if (d != null && d instanceof TransitionDrawable) { ((TransitionDrawable) d).resetTransition(); } } if (mTouchModeReset != null) { removeCallbacks(mTouchModeReset); } mTouchModeReset = new Runnable() { @Override public void run() { mTouchMode = TOUCH_MODE_REST; child.setPressed(false); setPressed(false); if (!mDataChanged) { performClick.run(); } } }; postDelayed(mTouchModeReset, ViewConfiguration.getPressedStateDuration()); } else { mTouchMode = TOUCH_MODE_REST; updateSelectorState(); } return true; } else if (!mDataChanged && mAdapter.isEnabled(motionPosition)) { performClick.run(); } } mTouchMode = TOUCH_MODE_REST; updateSelectorState(); break; case TOUCH_MODE_SCROLL: final int childCount = getChildCount(); if (childCount > 0) { final int firstChildTop = getChildAt(0).getTop(); final int lastChildBottom = getChildAt(childCount - 1).getBottom(); final int contentTop = mListPadding.top; final int contentBottom = getHeight() - mListPadding.bottom; if (mFirstPosition == 0 && firstChildTop >= contentTop && mFirstPosition + childCount < mItemCount && lastChildBottom <= getHeight() - contentBottom) { mTouchMode = TOUCH_MODE_REST; reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); } else { final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); final int initialVelocity = (int) (velocityTracker.getYVelocity(mActivePointerId) * mVelocityScale); // Fling if we have enough velocity and we aren't at a // boundary. // Since we can potentially overfling more than we can // overscroll, don't // allow the weird behavior where you can scroll to a // boundary then // fling further. if (Math.abs(initialVelocity) > mMinimumVelocity && !((mFirstPosition == 0 && firstChildTop == contentTop - mOverscrollDistance) || (mFirstPosition + childCount == mItemCount && lastChildBottom == contentBottom + mOverscrollDistance))) { if (mFlingRunnable == null) { mFlingRunnable = new FlingRunnable(); } reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING); mFlingRunnable.start(-initialVelocity); } else { mTouchMode = TOUCH_MODE_REST; reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); if (mFlingRunnable != null) { mFlingRunnable.endFling(); } if (mPositionScroller != null) { mPositionScroller.stop(); } } } } else { mTouchMode = TOUCH_MODE_REST; reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); } break; case TOUCH_MODE_OVERSCROLL: if (mFlingRunnable == null) { mFlingRunnable = new FlingRunnable(); } final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); final int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId); reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING); if (Math.abs(initialVelocity) > mMinimumVelocity) { mFlingRunnable.startOverfling(-initialVelocity); } else { mFlingRunnable.startSpringback(); } break; } setPressed(false); // Need to redraw since we probably aren't drawing the selector // anymore invalidate(); final Handler handler = getHandler(); if (handler != null) { handler.removeCallbacks(mPendingCheckForLongPress); } recycleVelocityTracker(); mActivePointerId = INVALID_POINTER; if (PROFILE_SCROLLING) { if (mScrollProfilingStarted) { Debug.stopMethodTracing(); mScrollProfilingStarted = false; } } break; } case MotionEvent.ACTION_CANCEL: { switch (mTouchMode) { case TOUCH_MODE_OVERSCROLL: if (mFlingRunnable == null) { mFlingRunnable = new FlingRunnable(); } mFlingRunnable.startSpringback(); break; case TOUCH_MODE_OVERFLING: // Do nothing - let it play out. break; default: mTouchMode = TOUCH_MODE_REST; setPressed(false); View motionView = this.getChildAt(mMotionPosition - mFirstPosition); if (motionView != null) { motionView.setPressed(false); } clearScrollingCache(); final Handler handler = getHandler(); if (handler != null) { handler.removeCallbacks(mPendingCheckForLongPress); } recycleVelocityTracker(); } mActivePointerId = INVALID_POINTER; break; } case MotionEvent.ACTION_POINTER_UP: { onSecondaryPointerUp(ev); final int x = mMotionX; final int y = mMotionY; final int motionPosition = pointToPosition(x, y); if (motionPosition >= 0) { // Remember where the motion event started v = getChildAt(motionPosition - mFirstPosition); mMotionViewOriginalTop = v.getTop(); mMotionPosition = motionPosition; } mLastY = y; break; } case MotionEvent.ACTION_POINTER_DOWN: { // New pointers take over dragging duties final int index = ev.getActionIndex(); final int id = ev.getPointerId(index); final int x = (int) ev.getX(index); final int y = (int) ev.getY(index); mMotionCorrection = 0; mActivePointerId = id; mMotionX = x; mMotionY = y; final int motionPosition = pointToPosition(x, y); if (motionPosition >= 0) { // Remember where the motion event started v = getChildAt(motionPosition - mFirstPosition); mMotionViewOriginalTop = v.getTop(); mMotionPosition = motionPosition; } mLastY = y; break; } } return true; }
From source file:com.appunite.list.AbsHorizontalListView.java
@Override public boolean onTouchEvent(MotionEvent ev) { if (!isEnabled()) { // A disabled view that is clickable still consumes the touch // events, it just doesn't respond to them. return isClickable() || isLongClickable(); }//from w w w .ja v a 2s .c o m if (mPositionScroller != null) { mPositionScroller.stop(); } if (!mIsAttached) { // Something isn't right. // Since we rely on being attached to get data set change notifications, // don't risk doing anything where we might try to resync and find things // in a bogus state. return false; } final int action = ev.getAction(); View v; initVelocityTrackerIfNotExists(); mVelocityTracker.addMovement(ev); switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: { switch (mTouchMode) { case TOUCH_MODE_OVERFLING: { mFlingRunnable.endFling(); if (mPositionScroller != null) { mPositionScroller.stop(); } mTouchMode = TOUCH_MODE_OVERSCROLL; mMotionX = mLastX = (int) ev.getX(); mMotionY = (int) ev.getY(); mMotionCorrection = 0; mActivePointerId = ev.getPointerId(0); mDirection = 0; break; } default: { mActivePointerId = ev.getPointerId(0); final int x = (int) ev.getX(); final int y = (int) ev.getY(); int motionPosition = pointToPosition(x, y); if (!mDataChanged) { if ((mTouchMode != TOUCH_MODE_FLING) && (motionPosition >= 0) && (getAdapter().isEnabled(motionPosition))) { // User clicked on an actual view (and was not stopping a fling). // It might be a click or a scroll. Assume it is a click until // proven otherwise mTouchMode = TOUCH_MODE_DOWN; // FIXME Debounce if (mPendingCheckForTap == null) { mPendingCheckForTap = new CheckForTap(); } postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout()); } else { if (mTouchMode == TOUCH_MODE_FLING) { // Stopped a fling. It is a scroll. createScrollingCache(); mTouchMode = TOUCH_MODE_SCROLL; mMotionCorrection = 0; motionPosition = findMotionCol(x); mFlingRunnable.flywheelTouch(); } } } if (motionPosition >= 0) { // Remember where the motion event started v = getChildAt(motionPosition - mFirstPosition); mMotionViewOriginalLeft = v.getLeft(); } mMotionX = x; mMotionY = y; mMotionPosition = motionPosition; mLastX = Integer.MIN_VALUE; break; } } if (performButtonActionOnTouchDownUnhide(ev)) { if (mTouchMode == TOUCH_MODE_DOWN) { removeCallbacks(mPendingCheckForTap); } } break; } case MotionEvent.ACTION_MOVE: { int pointerIndex = ev.findPointerIndex(mActivePointerId); if (pointerIndex == -1) { pointerIndex = 0; mActivePointerId = ev.getPointerId(pointerIndex); } final int x = (int) ev.getX(pointerIndex); if (mDataChanged) { // Re-sync everything if data has been changed // since the scroll operation can query the adapter. layoutChildren(); } switch (mTouchMode) { case TOUCH_MODE_DOWN: case TOUCH_MODE_TAP: case TOUCH_MODE_DONE_WAITING: // Check if we have moved far enough that it looks more like a // scroll than a tap startScrollIfNeeded(x); break; case TOUCH_MODE_SCROLL: case TOUCH_MODE_OVERSCROLL: scrollIfNeeded(x); break; } break; } case MotionEvent.ACTION_UP: { switch (mTouchMode) { case TOUCH_MODE_DOWN: case TOUCH_MODE_TAP: case TOUCH_MODE_DONE_WAITING: final int motionPosition = mMotionPosition; final View child = getChildAt(motionPosition - mFirstPosition); final float y = ev.getY(); final boolean inList = y > mListPadding.top && y < getHeight() - mListPadding.bottom; if (child != null && !child.hasFocusable() && inList) { if (mTouchMode != TOUCH_MODE_DOWN) { child.setPressed(false); } if (mPerformClick == null) { mPerformClick = new PerformClick(); } final AbsHorizontalListView.PerformClick performClick = mPerformClick; performClick.mClickMotionPosition = motionPosition; performClick.rememberWindowAttachCount(); mResurrectToPosition = motionPosition; if (mTouchMode == TOUCH_MODE_DOWN || mTouchMode == TOUCH_MODE_TAP) { final Handler handler = getHandler(); if (handler != null) { handler.removeCallbacks(mTouchMode == TOUCH_MODE_DOWN ? mPendingCheckForTap : mPendingCheckForLongPress); } mLayoutMode = LAYOUT_NORMAL; if (!mDataChanged && mAdapter.isEnabled(motionPosition)) { mTouchMode = TOUCH_MODE_TAP; setSelectedPositionInt(mMotionPosition); layoutChildren(); child.setPressed(true); positionSelector(mMotionPosition, child); setPressed(true); if (mSelector != null) { Drawable d = mSelector.getCurrent(); if (d != null && d instanceof TransitionDrawable) { ((TransitionDrawable) d).resetTransition(); } } if (mTouchModeReset != null) { removeCallbacks(mTouchModeReset); } mTouchModeReset = new Runnable() { @Override public void run() { mTouchModeReset = null; mTouchMode = TOUCH_MODE_REST; child.setPressed(false); setPressed(false); if (!mDataChanged) { performClick.run(); } } }; postDelayed(mTouchModeReset, ViewConfiguration.getPressedStateDuration()); } else { mTouchMode = TOUCH_MODE_REST; updateSelectorState(); } return true; } else if (!mDataChanged && mAdapter.isEnabled(motionPosition)) { performClick.run(); } } mTouchMode = TOUCH_MODE_REST; updateSelectorState(); break; case TOUCH_MODE_SCROLL: final int childCount = getChildCount(); if (childCount > 0) { final int firstChildLeft = getChildAt(0).getLeft(); final int lastChildRight = getChildAt(childCount - 1).getRight(); final int contentLeft = mListPadding.left; final int contentRight = getWidth() - mListPadding.right; if (mFirstPosition == 0 && firstChildLeft >= contentLeft && mFirstPosition + childCount < mItemCount && lastChildRight <= getWidth() - contentRight) { mTouchMode = TOUCH_MODE_REST; reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); } else { final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); final int initialVelocity = (int) (velocityTracker.getXVelocity(mActivePointerId) * mVelocityScale); // Fling if we have enough velocity and we aren't at a boundary. // Since we can potentially overfling more than we can overscroll, don't // allow the weird behavior where you can scroll to a boundary then // fling further. if (Math.abs(initialVelocity) > mMinimumVelocity && !((mFirstPosition == 0 && firstChildLeft == contentLeft - mOverscrollDistance) || (mFirstPosition + childCount == mItemCount && lastChildRight == contentRight + mOverscrollDistance))) { if (mFlingRunnable == null) { mFlingRunnable = new FlingRunnable(); } reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING); mFlingRunnable.start(-initialVelocity); } else { mTouchMode = TOUCH_MODE_REST; reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); if (mFlingRunnable != null) { mFlingRunnable.endFling(); } if (mPositionScroller != null) { mPositionScroller.stop(); } } } } else { mTouchMode = TOUCH_MODE_REST; reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); } break; case TOUCH_MODE_OVERSCROLL: if (mFlingRunnable == null) { mFlingRunnable = new FlingRunnable(); } final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); final int initialVelocity = (int) velocityTracker.getXVelocity(mActivePointerId); reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING); if (Math.abs(initialVelocity) > mMinimumVelocity) { mFlingRunnable.startOverfling(-initialVelocity); } else { mFlingRunnable.startSpringback(); } break; } setPressed(false); if (mEdgeGlowLeft != null) { mEdgeGlowLeft.onRelease(); mEdgeGlowRight.onRelease(); } // Need to redraw since we probably aren't drawing the selector anymore invalidate(); final Handler handler = getHandler(); if (handler != null) { handler.removeCallbacks(mPendingCheckForLongPress); } recycleVelocityTracker(); mActivePointerId = INVALID_POINTER; if (PROFILE_SCROLLING) { if (mScrollProfilingStarted) { Debug.stopMethodTracing(); mScrollProfilingStarted = false; } } // FIXME not needed bacaues we could not implement strict span (j.m.) // if (mScrollStrictSpan != null) { // mScrollStrictSpan.finish(); // mScrollStrictSpan = null; // } break; } case MotionEvent.ACTION_CANCEL: { switch (mTouchMode) { case TOUCH_MODE_OVERSCROLL: if (mFlingRunnable == null) { mFlingRunnable = new FlingRunnable(); } mFlingRunnable.startSpringback(); break; case TOUCH_MODE_OVERFLING: // Do nothing - let it play out. break; default: mTouchMode = TOUCH_MODE_REST; setPressed(false); View motionView = this.getChildAt(mMotionPosition - mFirstPosition); if (motionView != null) { motionView.setPressed(false); } clearScrollingCache(); final Handler handler = getHandler(); if (handler != null) { handler.removeCallbacks(mPendingCheckForLongPress); } recycleVelocityTracker(); } if (mEdgeGlowLeft != null) { mEdgeGlowLeft.onRelease(); mEdgeGlowRight.onRelease(); } mActivePointerId = INVALID_POINTER; break; } case MotionEvent.ACTION_POINTER_UP: { onSecondaryPointerUp(ev); final int x = mMotionX; final int y = mMotionY; final int motionPosition = pointToPosition(x, y); if (motionPosition >= 0) { // Remember where the motion event started v = getChildAt(motionPosition - mFirstPosition); mMotionViewOriginalLeft = v.getLeft(); mMotionPosition = motionPosition; } mLastX = x; break; } case MotionEvent.ACTION_POINTER_DOWN: { // New pointers take over dragging duties final int index = ev.getActionIndex(); final int id = ev.getPointerId(index); final int x = (int) ev.getX(index); final int y = (int) ev.getY(index); mMotionCorrection = 0; mActivePointerId = id; mMotionX = x; mMotionY = y; final int motionPosition = pointToPosition(x, y); if (motionPosition >= 0) { // Remember where the motion event started v = getChildAt(motionPosition - mFirstPosition); mMotionViewOriginalLeft = v.getLeft(); mMotionPosition = motionPosition; } mLastX = x; break; } } return true; }
From source file:com.appunite.list.AbsListView.java
@Override public boolean onTouchEvent(MotionEvent ev) { if (!isEnabled()) { // A disabled view that is clickable still consumes the touch // events, it just doesn't respond to them. return isClickable() || isLongClickable(); }/*from w w w . j a va 2 s . c o m*/ if (mPositionScroller != null) { mPositionScroller.stop(); } if (!mIsAttached) { // Something isn't right. // Since we rely on being attached to get data set change notifications, // don't risk doing anything where we might try to resync and find things // in a bogus state. return false; } if (mFastScroller != null) { boolean intercepted = mFastScroller.onTouchEvent(ev); if (intercepted) { return true; } } final int action = ev.getAction(); View v; initVelocityTrackerIfNotExists(); mVelocityTracker.addMovement(ev); switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: { switch (mTouchMode) { case TOUCH_MODE_OVERFLING: { mFlingRunnable.endFling(); if (mPositionScroller != null) { mPositionScroller.stop(); } mTouchMode = TOUCH_MODE_OVERSCROLL; mMotionX = (int) ev.getX(); mMotionY = mLastY = (int) ev.getY(); mMotionCorrection = 0; mActivePointerId = ev.getPointerId(0); mDirection = 0; break; } default: { mActivePointerId = ev.getPointerId(0); final int x = (int) ev.getX(); final int y = (int) ev.getY(); int motionPosition = pointToPosition(x, y); if (!mDataChanged) { if ((mTouchMode != TOUCH_MODE_FLING) && (motionPosition >= 0) && (getAdapter().isEnabled(motionPosition))) { // User clicked on an actual view (and was not stopping a fling). // It might be a click or a scroll. Assume it is a click until // proven otherwise mTouchMode = TOUCH_MODE_DOWN; // FIXME Debounce if (mPendingCheckForTap == null) { mPendingCheckForTap = new CheckForTap(); } postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout()); } else { if (mTouchMode == TOUCH_MODE_FLING) { // Stopped a fling. It is a scroll. createScrollingCache(); mTouchMode = TOUCH_MODE_SCROLL; mMotionCorrection = 0; motionPosition = findMotionRow(y); mFlingRunnable.flywheelTouch(); } } } if (motionPosition >= 0) { // Remember where the motion event started v = getChildAt(motionPosition - mFirstPosition); mMotionViewOriginalTop = v.getTop(); } mMotionX = x; mMotionY = y; mMotionPosition = motionPosition; mLastY = Integer.MIN_VALUE; break; } } if (performButtonActionOnTouchDownUnhide(ev)) { if (mTouchMode == TOUCH_MODE_DOWN) { removeCallbacks(mPendingCheckForTap); } } break; } case MotionEvent.ACTION_MOVE: { int pointerIndex = ev.findPointerIndex(mActivePointerId); if (pointerIndex == -1) { pointerIndex = 0; mActivePointerId = ev.getPointerId(pointerIndex); } final int y = (int) ev.getY(pointerIndex); if (mDataChanged) { // Re-sync everything if data has been changed // since the scroll operation can query the adapter. layoutChildren(); } switch (mTouchMode) { case TOUCH_MODE_DOWN: case TOUCH_MODE_TAP: case TOUCH_MODE_DONE_WAITING: // Check if we have moved far enough that it looks more like a // scroll than a tap startScrollIfNeeded(y); break; case TOUCH_MODE_SCROLL: case TOUCH_MODE_OVERSCROLL: scrollIfNeeded(y); break; } break; } case MotionEvent.ACTION_UP: { switch (mTouchMode) { case TOUCH_MODE_DOWN: case TOUCH_MODE_TAP: case TOUCH_MODE_DONE_WAITING: final int motionPosition = mMotionPosition; final View child = getChildAt(motionPosition - mFirstPosition); final float x = ev.getX(); final boolean inList = x > mListPadding.left && x < getWidth() - mListPadding.right; if (child != null && !child.hasFocusable() && inList) { if (mTouchMode != TOUCH_MODE_DOWN) { child.setPressed(false); } if (mPerformClick == null) { mPerformClick = new PerformClick(); } final AbsListView.PerformClick performClick = mPerformClick; performClick.mClickMotionPosition = motionPosition; performClick.rememberWindowAttachCount(); mResurrectToPosition = motionPosition; if (mTouchMode == TOUCH_MODE_DOWN || mTouchMode == TOUCH_MODE_TAP) { final Handler handler = getHandler(); if (handler != null) { handler.removeCallbacks(mTouchMode == TOUCH_MODE_DOWN ? mPendingCheckForTap : mPendingCheckForLongPress); } mLayoutMode = LAYOUT_NORMAL; if (!mDataChanged && mAdapter.isEnabled(motionPosition)) { mTouchMode = TOUCH_MODE_TAP; setSelectedPositionInt(mMotionPosition); layoutChildren(); child.setPressed(true); positionSelector(mMotionPosition, child); setPressed(true); if (mSelector != null) { Drawable d = mSelector.getCurrent(); if (d != null && d instanceof TransitionDrawable) { ((TransitionDrawable) d).resetTransition(); } } if (mTouchModeReset != null) { removeCallbacks(mTouchModeReset); } mTouchModeReset = new Runnable() { @Override public void run() { mTouchModeReset = null; mTouchMode = TOUCH_MODE_REST; child.setPressed(false); setPressed(false); if (!mDataChanged) { performClick.run(); } } }; postDelayed(mTouchModeReset, ViewConfiguration.getPressedStateDuration()); } else { mTouchMode = TOUCH_MODE_REST; updateSelectorState(); } return true; } else if (!mDataChanged && mAdapter.isEnabled(motionPosition)) { performClick.run(); } } mTouchMode = TOUCH_MODE_REST; updateSelectorState(); break; case TOUCH_MODE_SCROLL: final int childCount = getChildCount(); if (childCount > 0) { final int firstChildTop = getChildAt(0).getTop(); final int lastChildBottom = getChildAt(childCount - 1).getBottom(); final int contentTop = mListPadding.top; final int contentBottom = getHeight() - mListPadding.bottom; if (mFirstPosition == 0 && firstChildTop >= contentTop && mFirstPosition + childCount < mItemCount && lastChildBottom <= getHeight() - contentBottom) { mTouchMode = TOUCH_MODE_REST; reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); } else { final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); final int initialVelocity = (int) (velocityTracker.getYVelocity(mActivePointerId) * mVelocityScale); // Fling if we have enough velocity and we aren't at a boundary. // Since we can potentially overfling more than we can overscroll, don't // allow the weird behavior where you can scroll to a boundary then // fling further. if (Math.abs(initialVelocity) > mMinimumVelocity && !((mFirstPosition == 0 && firstChildTop == contentTop - mOverscrollDistance) || (mFirstPosition + childCount == mItemCount && lastChildBottom == contentBottom + mOverscrollDistance))) { if (mFlingRunnable == null) { mFlingRunnable = new FlingRunnable(); } reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING); mFlingRunnable.start(-initialVelocity); } else { mTouchMode = TOUCH_MODE_REST; reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); if (mFlingRunnable != null) { mFlingRunnable.endFling(); } if (mPositionScroller != null) { mPositionScroller.stop(); } } } } else { mTouchMode = TOUCH_MODE_REST; reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); } break; case TOUCH_MODE_OVERSCROLL: if (mFlingRunnable == null) { mFlingRunnable = new FlingRunnable(); } final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); final int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId); reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING); if (Math.abs(initialVelocity) > mMinimumVelocity) { mFlingRunnable.startOverfling(-initialVelocity); } else { mFlingRunnable.startSpringback(); } break; } setPressed(false); if (mEdgeGlowTop != null) { mEdgeGlowTop.onRelease(); mEdgeGlowBottom.onRelease(); } // Need to redraw since we probably aren't drawing the selector anymore invalidate(); final Handler handler = getHandler(); if (handler != null) { handler.removeCallbacks(mPendingCheckForLongPress); } recycleVelocityTracker(); mActivePointerId = INVALID_POINTER; if (PROFILE_SCROLLING) { if (mScrollProfilingStarted) { Debug.stopMethodTracing(); mScrollProfilingStarted = false; } } // FIXME not needed bacaues we could not implement strict span (j.m.) // if (mScrollStrictSpan != null) { // mScrollStrictSpan.finish(); // mScrollStrictSpan = null; // } break; } case MotionEvent.ACTION_CANCEL: { switch (mTouchMode) { case TOUCH_MODE_OVERSCROLL: if (mFlingRunnable == null) { mFlingRunnable = new FlingRunnable(); } mFlingRunnable.startSpringback(); break; case TOUCH_MODE_OVERFLING: // Do nothing - let it play out. break; default: mTouchMode = TOUCH_MODE_REST; setPressed(false); View motionView = this.getChildAt(mMotionPosition - mFirstPosition); if (motionView != null) { motionView.setPressed(false); } clearScrollingCache(); final Handler handler = getHandler(); if (handler != null) { handler.removeCallbacks(mPendingCheckForLongPress); } recycleVelocityTracker(); } if (mEdgeGlowTop != null) { mEdgeGlowTop.onRelease(); mEdgeGlowBottom.onRelease(); } mActivePointerId = INVALID_POINTER; break; } case MotionEvent.ACTION_POINTER_UP: { onSecondaryPointerUp(ev); final int x = mMotionX; final int y = mMotionY; final int motionPosition = pointToPosition(x, y); if (motionPosition >= 0) { // Remember where the motion event started v = getChildAt(motionPosition - mFirstPosition); mMotionViewOriginalTop = v.getTop(); mMotionPosition = motionPosition; } mLastY = y; break; } case MotionEvent.ACTION_POINTER_DOWN: { // New pointers take over dragging duties final int index = MotionEventCompat.getActionIndex(ev); final int id = ev.getPointerId(index); final int x = (int) ev.getX(index); final int y = (int) ev.getY(index); mMotionCorrection = 0; mActivePointerId = id; mMotionX = x; mMotionY = y; final int motionPosition = pointToPosition(x, y); if (motionPosition >= 0) { // Remember where the motion event started v = getChildAt(motionPosition - mFirstPosition); mMotionViewOriginalTop = v.getTop(); mMotionPosition = motionPosition; } mLastY = y; break; } } return true; }