Search in sources :

Example 71 with VelocityTracker

use of android.view.VelocityTracker in project UltimateAndroid by cymcsg.

the class ViewPager method endFakeDrag.

/**
     * End a fake drag of the pager.
     *
     * @see #beginFakeDrag()
     * @see #fakeDragBy(float)
     */
public void endFakeDrag() {
    if (!mFakeDragging) {
        throw new IllegalStateException("No fake drag in progress. Call beginFakeDrag first.");
    }
    final VelocityTracker velocityTracker = mVelocityTracker;
    velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
    int initialVelocity = (int) VelocityTrackerCompat.getXVelocity(velocityTracker, mActivePointerId);
    mPopulatePending = true;
    final int width = getClientWidth();
    final int scrollX = getScrollX();
    final ItemInfo ii = infoForCurrentScrollPosition();
    final int currentPage = ii.position;
    final float pageOffset = (((float) scrollX / width) - ii.offset) / ii.widthFactor;
    final int totalDelta = (int) (mLastMotionX - mInitialMotionX);
    int nextPage = determineTargetPage(currentPage, pageOffset, initialVelocity, totalDelta);
    setCurrentItemInternal(nextPage, true, true, initialVelocity);
    endDrag();
    mFakeDragging = false;
}
Also used : VelocityTracker(android.view.VelocityTracker)

Example 72 with VelocityTracker

use of android.view.VelocityTracker in project UltimateAndroid by cymcsg.

the class ViewPager method onTouchEvent.

@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (mFakeDragging) {
        // (It is likely that the user is multi-touching the screen.)
        return true;
    }
    if (ev.getAction() == MotionEvent.ACTION_DOWN && ev.getEdgeFlags() != 0) {
        // 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();
                // 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);
                if (DEBUG)
                    Log.v(TAG, "Moved x to " + x + "," + y + " diff=" + xDiff + "," + yDiff);
                if (xDiff > mTouchSlop && xDiff > yDiff) {
                    if (DEBUG)
                        Log.v(TAG, "Starting drag!");
                    mIsBeingDragged = true;
                    requestParentDisallowInterceptTouchEvent(true);
                    mLastMotionX = x - mInitialMotionX > 0 ? mInitialMotionX + mTouchSlop : mInitialMotionX - mTouchSlop;
                    mLastMotionY = y;
                    setScrollState(SCROLL_STATE_DRAGGING);
                    setScrollingCacheEnabled(true);
                    // Disallow Parent Intercept, just in case
                    ViewParent parent = getParent();
                    if (parent != null) {
                        parent.requestDisallowInterceptTouchEvent(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);
                final float x = MotionEventCompat.getX(ev, activePointerIndex);
                needsInvalidate |= performDrag(x);
            }
            break;
        case MotionEvent.ACTION_UP:
            if (mIsBeingDragged) {
                final VelocityTracker velocityTracker = mVelocityTracker;
                velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
                int initialVelocity = (int) VelocityTrackerCompat.getXVelocity(velocityTracker, mActivePointerId);
                mPopulatePending = true;
                final int width = getClientWidth();
                final int scrollX = getScrollX();
                final ItemInfo ii = infoForCurrentScrollPosition();
                final int currentPage = ii.position;
                final float pageOffset = (((float) scrollX / width) - ii.offset) / ii.widthFactor;
                final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
                final float x = MotionEventCompat.getX(ev, activePointerIndex);
                final int totalDelta = (int) (x - mInitialMotionX);
                int nextPage = determineTargetPage(currentPage, pageOffset, initialVelocity, totalDelta);
                setCurrentItemInternal(nextPage, true, true, initialVelocity);
                mActivePointerId = INVALID_POINTER;
                endDrag();
                needsInvalidate = mLeftEdge.onRelease() | mRightEdge.onRelease();
            }
            break;
        case MotionEvent.ACTION_CANCEL:
            if (mIsBeingDragged) {
                scrollToItem(mCurItem, true, 0, false);
                mActivePointerId = INVALID_POINTER;
                endDrag();
                needsInvalidate = mLeftEdge.onRelease() | mRightEdge.onRelease();
            }
            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);
            mLastMotionX = MotionEventCompat.getX(ev, MotionEventCompat.findPointerIndex(ev, mActivePointerId));
            break;
    }
    if (needsInvalidate) {
        ViewCompat.postInvalidateOnAnimation(this);
    }
    return true;
}
Also used : VelocityTracker(android.view.VelocityTracker) ViewParent(android.view.ViewParent)

Example 73 with VelocityTracker

use of android.view.VelocityTracker in project SimplifyReader by chentao0707.

the class PLAAbsListView method onTouchEvent.

@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (!isEnabled()) {
        // events, it just doesn't respond to them.
        return isClickable() || isLongClickable();
    }
    final int action = ev.getAction();
    View v;
    int deltaY;
    if (mVelocityTracker == null) {
        mVelocityTracker = VelocityTracker.obtain();
    }
    mVelocityTracker.addMovement(ev);
    switch(action & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
            {
                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 (ev.getEdgeFlags() != 0 && motionPosition < 0) {
                            // code in ViewRoot to try to find a nearby view to select
                            return false;
                        }
                        if (mTouchMode == TOUCH_MODE_FLING) {
                            // Stopped a fling. It is a scroll.
                            createScrollingCache();
                            mTouchMode = TOUCH_MODE_SCROLL;
                            mMotionCorrection = 0;
                            motionPosition = findMotionRow(y);
                            reportScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
                        }
                    }
                }
                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;
            }
        case MotionEvent.ACTION_MOVE:
            {
                final int pointerIndex = ev.findPointerIndex(mActivePointerId);
                final int y = (int) ev.getY(pointerIndex);
                deltaY = y - mMotionY;
                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(deltaY);
                        break;
                    case TOUCH_MODE_SCROLL:
                        if (PROFILE_SCROLLING) {
                            if (!mScrollProfilingStarted) {
                                Debug.startMethodTracing("AbsListViewScroll");
                                mScrollProfilingStarted = true;
                            }
                        }
                        if (y != mLastY) {
                            deltaY -= mMotionCorrection;
                            int incrementalDeltaY = mLastY != Integer.MIN_VALUE ? y - mLastY : deltaY;
                            // No need to do all this work if we're not going to move anyway
                            boolean atEdge = false;
                            if (incrementalDeltaY != 0) {
                                atEdge = trackMotionScroll(deltaY, incrementalDeltaY);
                            }
                            // Check to see if we have bumped into the scroll limit
                            if (atEdge && getChildCount() > 0) {
                                // Treat this like we're starting a new scroll from the current
                                // position. This will let the user start scrolling back into
                                // content immediately rather than needing to scroll back to the
                                // point where they hit the limit first.
                                int motionPosition = findMotionRow(y);
                                if (motionPosition >= 0) {
                                    final View motionView = getChildAt(motionPosition - mFirstPosition);
                                    mMotionViewOriginalTop = motionView.getTop();
                                }
                                mMotionY = y;
                                mMotionPosition = motionPosition;
                                invalidate();
                            }
                            mLastY = 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);
                        if (child != null && !child.hasFocusable()) {
                            if (mTouchMode != TOUCH_MODE_DOWN) {
                                child.setPressed(false);
                            }
                            if (mPerformClick == null) {
                                mPerformClick = new PerformClick();
                            }
                            final PerformClick performClick = mPerformClick;
                            performClick.mChild = child;
                            performClick.mClickMotionPosition = motionPosition;
                            performClick.rememberWindowAttachCount();
                            mResurrectToPosition = motionPosition;
                            if (mTouchMode == TOUCH_MODE_DOWN || mTouchMode == TOUCH_MODE_TAP) {
                                mLayoutMode = LAYOUT_NORMAL;
                                if (!mDataChanged && mAdapter.isEnabled(motionPosition)) {
                                    mTouchMode = TOUCH_MODE_TAP;
                                    layoutChildren();
                                    child.setPressed(true);
                                    positionSelector(child);
                                    setPressed(true);
                                    if (mSelector != null) {
                                        Drawable d = mSelector.getCurrent();
                                        if (d != null && d instanceof TransitionDrawable) {
                                            ((TransitionDrawable) d).resetTransition();
                                        }
                                    }
                                    postDelayed(new Runnable() {

                                        public void run() {
                                            child.setPressed(false);
                                            setPressed(false);
                                            if (!mDataChanged) {
                                                post(performClick);
                                            }
                                            mTouchMode = TOUCH_MODE_REST;
                                        }
                                    }, ViewConfiguration.getPressedStateDuration());
                                } else {
                                    mTouchMode = TOUCH_MODE_REST;
                                }
                                return true;
                            } else if (!mDataChanged && mAdapter.isEnabled(motionPosition)) {
                                post(performClick);
                            }
                        }
                        mTouchMode = TOUCH_MODE_REST;
                        break;
                    case TOUCH_MODE_SCROLL:
                        final int childCount = getChildCount();
                        if (childCount > 0) {
                            int top = getFillChildTop();
                            int bottom = getFillChildBottom();
                            if (mFirstPosition == 0 && top >= mListPadding.top && mFirstPosition + childCount < mItemCount && bottom <= getHeight() - mListPadding.bottom) {
                                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);
                                if (Math.abs(initialVelocity) > mMinimumVelocity) {
                                    if (mFlingRunnable == null) {
                                        mFlingRunnable = new FlingRunnable();
                                    }
                                    reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
                                    mFlingRunnable.start(-initialVelocity);
                                } else {
                                    mTouchMode = TOUCH_MODE_REST;
                                    reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
                                }
                            }
                        } else {
                            mTouchMode = TOUCH_MODE_REST;
                            reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
                        }
                        break;
                }
                setPressed(false);
                // Need to redraw since we probably aren't drawing the selector anymore
                invalidate();
                if (mVelocityTracker != null) {
                    mVelocityTracker.recycle();
                    mVelocityTracker = null;
                }
                mActivePointerId = INVALID_POINTER;
                if (PROFILE_SCROLLING) {
                    if (mScrollProfilingStarted) {
                        Debug.stopMethodTracing();
                        mScrollProfilingStarted = false;
                    }
                }
                break;
            }
        case MotionEvent.ACTION_CANCEL:
            {
                mTouchMode = TOUCH_MODE_REST;
                setPressed(false);
                View motionView = this.getChildAt(mMotionPosition - mFirstPosition);
                if (motionView != null) {
                    motionView.setPressed(false);
                }
                clearScrollingCache();
                if (mVelocityTracker != null) {
                    mVelocityTracker.recycle();
                    mVelocityTracker = null;
                }
                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;
            }
    }
    return true;
}
Also used : TransitionDrawable(android.graphics.drawable.TransitionDrawable) VelocityTracker(android.view.VelocityTracker) Drawable(android.graphics.drawable.Drawable) TransitionDrawable(android.graphics.drawable.TransitionDrawable) View(android.view.View)

Example 74 with VelocityTracker

use of android.view.VelocityTracker in project Launcher3 by chislon.

the class PagedView method onTouchEvent.

@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (DISABLE_TOUCH_INTERACTION) {
        return false;
    }
    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:
            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);
                // 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;
                    }
                    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();
                }
            } 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;
}
Also used : VelocityTracker(android.view.VelocityTracker) PointF(android.graphics.PointF) AnimatorSet(android.animation.AnimatorSet) View(android.view.View)

Example 75 with VelocityTracker

use of android.view.VelocityTracker in project AndroidTreeView by bmelnychuk.

the class TwoDScrollView method onTouchEvent.

@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (ev.getAction() == MotionEvent.ACTION_DOWN && ev.getEdgeFlags() != 0) {
        // descendants.
        return false;
    }
    if (!canScroll()) {
        return false;
    }
    if (mVelocityTracker == null) {
        mVelocityTracker = VelocityTracker.obtain();
    }
    mVelocityTracker.addMovement(ev);
    final int action = ev.getAction();
    final float y = ev.getY();
    final float x = ev.getX();
    switch(action) {
        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
            mLastMotionY = y;
            mLastMotionX = x;
            break;
        case MotionEvent.ACTION_MOVE:
            // Scroll to follow the motion event
            int deltaX = (int) (mLastMotionX - x);
            int deltaY = (int) (mLastMotionY - y);
            mLastMotionX = x;
            mLastMotionY = y;
            if (deltaX < 0) {
                if (getScrollX() < 0) {
                    deltaX = 0;
                }
            } else if (deltaX > 0) {
                final int rightEdge = getWidth() - getPaddingRight();
                final int availableToScroll = getChildAt(0).getRight() - getScrollX() - rightEdge;
                if (availableToScroll > 0) {
                    deltaX = Math.min(availableToScroll, deltaX);
                } else {
                    deltaX = 0;
                }
            }
            if (deltaY < 0) {
                if (getScrollY() < 0) {
                    deltaY = 0;
                }
            } else if (deltaY > 0) {
                final int bottomEdge = getHeight() - getPaddingBottom();
                final int availableToScroll = getChildAt(0).getBottom() - getScrollY() - bottomEdge;
                if (availableToScroll > 0) {
                    deltaY = Math.min(availableToScroll, deltaY);
                } else {
                    deltaY = 0;
                }
            }
            if (deltaY != 0 || deltaX != 0)
                scrollBy(deltaX, deltaY);
            break;
        case MotionEvent.ACTION_UP:
            final VelocityTracker velocityTracker = mVelocityTracker;
            velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
            int initialXVelocity = (int) velocityTracker.getXVelocity();
            int initialYVelocity = (int) velocityTracker.getYVelocity();
            if ((Math.abs(initialXVelocity) + Math.abs(initialYVelocity) > mMinimumVelocity) && getChildCount() > 0) {
                fling(-initialXVelocity, -initialYVelocity);
            }
            if (mVelocityTracker != null) {
                mVelocityTracker.recycle();
                mVelocityTracker = null;
            }
    }
    return true;
}
Also used : VelocityTracker(android.view.VelocityTracker)

Aggregations

VelocityTracker (android.view.VelocityTracker)125 ViewParent (android.view.ViewParent)32 Paint (android.graphics.Paint)23 View (android.view.View)14 MediumTest (android.test.suitebuilder.annotation.MediumTest)12 Drawable (android.graphics.drawable.Drawable)10 TransitionDrawable (android.graphics.drawable.TransitionDrawable)10 MotionEvent (android.view.MotionEvent)9 Handler (android.os.Handler)3 AnimatorSet (android.animation.AnimatorSet)2 SuppressLint (android.annotation.SuppressLint)2 PointF (android.graphics.PointF)2 Rect (android.graphics.Rect)1 ViewPager (android.support.v4.view.ViewPager)1 TextPaint (android.text.TextPaint)1 AccelerateInterpolator (android.view.animation.AccelerateInterpolator)1 DecelerateInterpolator (android.view.animation.DecelerateInterpolator)1 ListView (android.widget.ListView)1 OnClickHandler (android.widget.RemoteViews.OnClickHandler)1 Field (java.lang.reflect.Field)1