Android Launcher2之页面滑动

来源:互联网 发布:海颐软件北京分公司 编辑:程序博客网 时间:2024/06/06 16:53

PagedView.java

下面是PagedView的消息流程传递流程图

//滑动结束状态protected final static int TOUCH_STATE_REST = 0;//正在滑动protected final static int TOUCH_STATE_SCROLLING = 1;//滑动到上一页protected final static int TOUCH_STATE_PREV_PAGE = 2;//滑动到下一页protected final static int TOUCH_STATE_NEXT_PAGE = 3;


 @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        /*         * This method JUST determines whether we want to intercept the motion.         * If we return true, onTouchEvent will be called and we do the actual         * scrolling there.         */        acquireVelocityTrackerAndAddMovement(ev);        // Skip touch handling if there are no pages to swipe        if (getChildCount() <= 0) return super.onInterceptTouchEvent(ev);        /*         * Shortcut the most recurring case: the user is in the dragging         * state and he is moving his finger.  We want to intercept this         * motion.         */        final int action = ev.getAction();        if ((action == MotionEvent.ACTION_MOVE) &&                (mTouchState == TOUCH_STATE_SCROLLING)) {            return true;        }        switch (action & MotionEvent.ACTION_MASK) {            case MotionEvent.ACTION_MOVE: {                /*                 * mIsBeingDragged == false, otherwise the shortcut would have caught it. Check                 * whether the user has moved far enough from his original down touch.                 */                if (mActivePointerId != INVALID_POINTER) {                    determineScrollingStart(ev);                    break;                }                // if mActivePointerId is INVALID_POINTER, then we must have missed an ACTION_DOWN                // event. in that case, treat the first occurence of a move event as a ACTION_DOWN                // i.e. fall through to the next case (don't break)                // (We sometimes miss ACTION_DOWN events in Workspace because it ignores all events                // while it's small- this was causing a crash before we checked for INVALID_POINTER)            }            case MotionEvent.ACTION_DOWN: {                final float x = ev.getX();                final float y = ev.getY();                // Remember location of down touch                mDownMotionX = x;                mLastMotionX = x;                mLastMotionY = y;                mLastMotionXRemainder = 0;                mTotalMotionX = 0;                mActivePointerId = ev.getPointerId(0);                mAllowLongPress = true;                /*                 * If being flinged and user touches the screen, initiate drag;                 * otherwise don't.  mScroller.isFinished should be false when                 * being flinged.                 */                final int xDist = Math.abs(mScroller.getFinalX() - mScroller.getCurrX());                final boolean finishedScrolling = (mScroller.isFinished() || xDist < mTouchSlop);                if (finishedScrolling) {                    mTouchState = TOUCH_STATE_REST;                    mScroller.abortAnimation();                } else {                    mTouchState = TOUCH_STATE_SCROLLING;                }                // check if this can be the beginning of a tap on the side of the pages                // to scroll the current page                if (mTouchState != TOUCH_STATE_PREV_PAGE && mTouchState != TOUCH_STATE_NEXT_PAGE) {                    if (getChildCount() > 0) {                        if (hitsPreviousPage(x, y)) {                            mTouchState = TOUCH_STATE_PREV_PAGE;                        } else if (hitsNextPage(x, y)) {                            mTouchState = TOUCH_STATE_NEXT_PAGE;                        }                    }                }                break;            }            case MotionEvent.ACTION_UP:            case MotionEvent.ACTION_CANCEL:                mTouchState = TOUCH_STATE_REST;                mAllowLongPress = false;                mActivePointerId = INVALID_POINTER;                releaseVelocityTracker();                break;            case MotionEvent.ACTION_POINTER_UP:                onSecondaryPointerUp(ev);                releaseVelocityTracker();                break;        }        /*         * The only time we want to intercept motion events is if we are in the         * drag mode.         */        return mTouchState != TOUCH_STATE_REST;    }

@Override    public boolean onTouchEvent(MotionEvent 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();            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);                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 {                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 = getScaledMeasuredWidth(getPageAt(mCurrentPage));                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;                // 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 (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 {                onUnhandledTap(ev);            }            mTouchState = TOUCH_STATE_REST;            mActivePointerId = INVALID_POINTER;            releaseVelocityTracker();            break;        case MotionEvent.ACTION_CANCEL:            if (mTouchState == TOUCH_STATE_SCROLLING) {                snapToDestination();            }            mTouchState = TOUCH_STATE_REST;            mActivePointerId = INVALID_POINTER;            releaseVelocityTracker();            break;        case MotionEvent.ACTION_POINTER_UP:            onSecondaryPointerUp(ev);            break;        }        return true;    }


/**     * Implement this method to handle generic motion events.     * <p>     * Generic motion events describe joystick movements, mouse hovers, track pad     * touches, scroll wheel movements and other input events.  The     * {@link MotionEvent#getSource() source} of the motion event specifies     * the class of input that was received.  Implementations of this method     * must examine the bits in the source before processing the event.     * The following code example shows how this is done.     * </p><p>     * Generic motion events with source class {@link InputDevice#SOURCE_CLASS_POINTER}     * are delivered to the view under the pointer.  All other generic motion events are     * delivered to the focused view.     * </p>     * <pre> public boolean onGenericMotionEvent(MotionEvent event) {     *     if (event.isFromSource(InputDevice.SOURCE_CLASS_JOYSTICK)) {     *         if (event.getAction() == MotionEvent.ACTION_MOVE) {     *             // process the joystick movement...     *             return true;     *         }     *     }     *     if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {     *         switch (event.getAction()) {     *             case MotionEvent.ACTION_HOVER_MOVE:     *                 // process the mouse hover movement...     *                 return true;     *             case MotionEvent.ACTION_SCROLL:     *                 // process the scroll wheel movement...     *                 return true;     *         }     *     }     *     return super.onGenericMotionEvent(event);     * }</pre>     *     * @param event The generic motion event being processed.     * @return True if the event was handled, false otherwise.     */
 @Override    public boolean onGenericMotionEvent(MotionEvent event) {        if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {            switch (event.getAction()) {                case MotionEvent.ACTION_SCROLL: {                    // Handle mouse (or ext. device) by shifting the page depending on the scroll                    final float vscroll;                    final float hscroll;                    if ((event.getMetaState() & KeyEvent.META_SHIFT_ON) != 0) {                        vscroll = 0;                        hscroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL);                    } else {                        vscroll = -event.getAxisValue(MotionEvent.AXIS_VSCROLL);                        hscroll = event.getAxisValue(MotionEvent.AXIS_HSCROLL);                    if (hscroll != 0 || vscroll != 0) {                                            if (DEBUG) Log.d(TAG, "vscroll: " + vscroll + " ,hscroll:"                        + hscroll);                    }                        boolean isForwardScroll = isLayoutRtl() ? (hscroll < 0 || vscroll < 0)                                                         : (hscroll > 0 || vscroll > 0);                        if (isForwardScroll) {                            scrollRight();                        } else {                            scrollLeft();                        }                        return true;                    }                }            }        }        return super.onGenericMotionEvent(event);    }

onGenericMotionEvent 函数一般处理Generic motion events describe joystick movements, mouse hovers, track pad touches, scroll wheel movements and other input events,其他的都是由onTouchEvent 处理

0 0
原创粉丝点击