Launcher modification-source code tracking for switching between left and right sliding screens

Source: Internet
Author: User
Tags gety xdiff

In the android source code, how does one achieve screen jump? Start In workspace. java. In this class, the following methods are mainly rewritten to implement screen switching: onmeasure (), onlayout (), onintercepttouchevent (), ontouchevent, in addition, customscroller is used to smoothly transition between pages.

First, let's take a look at the onmeasure () method, which literally means measurement. It is mainly responsible for measuring the height and width of each control:

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        final int width = MeasureSpec.getSize(widthMeasureSpec);        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);        if (widthMode != MeasureSpec.EXACTLY) {            throw new IllegalStateException("Workspace can only be used in EXACTLY mode.");        }        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);        if (heightMode != MeasureSpec.EXACTLY) {            throw new IllegalStateException("Workspace can only be used in EXACTLY mode.");        }        // The children are given the same width and height as the workspace        final int count = getChildCount();        for (int i = 0; i < count; i++) {            getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);        }        //ADW: measure wallpaper when using old rendering    if(!lwpSupport){    if (mWallpaperLoaded) {        mWallpaperLoaded = false;        mWallpaperWidth = mWallpaperDrawable.getIntrinsicWidth();        mWallpaperHeight = mWallpaperDrawable.getIntrinsicHeight();    }    final int wallpaperWidth = mWallpaperWidth;    mWallpaperOffset = wallpaperWidth > width ? (count * width - wallpaperWidth) /            ((count - 1) * (float) width) : 1.0f;    }        if (mFirstLayout) {            scrollTo(mCurrentScreen * width, 0);            mScroller.startScroll(0, 0, mCurrentScreen * width, 0, 0);            if(lwpSupport)updateWallpaperOffset(width * (getChildCount() - 1));            mFirstLayout = false;        }    /*int max = 3;        int aW = getMeasuredWidth();        float w = aW / max;        maxPreviewWidth=(int) w;        maxPreviewHeight=(int) (getMeasuredHeight()*(w/getMeasuredWidth()));*/    }

Here, we get the width and height of the screen, then enumerate all the child views and set their layout (make them the same as the parent control ), in this way, each sub-view is filled with one of the pages that can be slide on the screen.
The onlayout () method is as follows:

protected void onLayout(boolean changed, int left, int top, int right, int bottom) {        int childLeft = 0;        final int count = getChildCount();        for (int i = 0; i < count; i++) {            final View child = getChildAt(i);            if (child.getVisibility() != View.GONE) {                final int childWidth = child.getMeasuredWidth();                child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight());                childLeft += childWidth;            }        }        //ADW:updateWallpaperoffset        if(lwpSupport){        if(mWallpaperScroll)        updateWallpaperOffset();        else        centerWallpaperOffset();        }    }

In the onlayout method, each sub-view is drawn horizontally. The height of the view is the same as that of the screen. The width is getchildcount ()-1 View of the screen width.

Let's take a look at the onintercepttouchevent () method:

public boolean onInterceptTouchEvent(MotionEvent ev) {    if(mStatus==SENSE_OPEN){    if(ev.getAction()==MotionEvent.ACTION_DOWN){    findClickedPreview(ev.getX(),ev.getY());    }    return true;    }        //Wysie: If multitouch event is detected        if (multiTouchController.onTouchEvent(ev)) {            return false;        }        if (mLocked || mLauncher.isAllAppsVisible()) {            return true;        }        /*         * 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.         */        /*         * 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_REST)) {            return true;        }        final float x = ev.getX();        final float y = ev.getY();        switch (action) {            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.                 */                /*                 * Locally do absolute value. mLastMotionX is set to the y value                 * of the down event.                 */                final int xDiff = (int) Math.abs(x - mLastMotionX);                final int yDiff = (int) Math.abs(y - mLastMotionY);                final int touchSlop = mTouchSlop;                boolean xMoved = xDiff > touchSlop;                boolean yMoved = yDiff > touchSlop;                if (xMoved || yMoved) {                    // If xDiff > yDiff means the finger path pitch is smaller than 45deg so we assume the user want to scroll X axis                    if (xDiff > yDiff) {                        // Scroll if the user moved far enough along the X axis                        mTouchState = TOUCH_STATE_SCROLLING;                        enableChildrenCache();                    }                    // If yDiff > xDiff means the finger path pitch is bigger than 45deg so we assume the user want to either scroll Y or Y-axis gesture                    else if (getOpenFolder()==null)                    {                    // As x scrolling is left untouched (more or less untouched;)), every gesture should start by dragging in Y axis. In fact I only consider useful, swipe up and down.                    // Guess if the first Pointer where the user click belongs to where a scrollable widget is.                mTouchedScrollableWidget = isWidgetAtLocationScrollable((int)mLastMotionX,(int)mLastMotionY);                    if (!mTouchedScrollableWidget)                    {                    // Only y axis movement. So may be a Swipe down or up gesture                    if ((y - mLastMotionY) > 0){                    if(Math.abs(y-mLastMotionY)>(touchSlop*2))mTouchState = TOUCH_SWIPE_DOWN_GESTURE;                    }else{                    if(Math.abs(y-mLastMotionY)>(touchSlop*2))mTouchState = TOUCH_SWIPE_UP_GESTURE;                    }                    }                    }                    // Either way, cancel any pending longpress                    if (mAllowLongPress) {                        mAllowLongPress = false;                        // Try canceling the long press. It could also have been scheduled                        // by a distant descendant, so use the mAllowLongPress flag to block                        // everything                        final View currentScreen = getChildAt(mCurrentScreen);                        currentScreen.cancelLongPress();                    }                }                break;            case MotionEvent.ACTION_DOWN:                // Remember location of down touch                mLastMotionX = x;                mLastMotionY = y;                mAllowLongPress = true;                /*                 * If being flinged and user touches the screen, initiate drag;                 * otherwise don't.  mScroller.isFinished should be false when                 * being flinged.                 */                mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST : TOUCH_STATE_SCROLLING;                break;            case MotionEvent.ACTION_CANCEL:            case MotionEvent.ACTION_UP:            if (mTouchState != TOUCH_STATE_SCROLLING && mTouchState != TOUCH_SWIPE_DOWN_GESTURE && mTouchState != TOUCH_SWIPE_UP_GESTURE) {                    final CellLayout currentScreen = (CellLayout) getChildAt(mCurrentScreen);                    if (!currentScreen.lastDownOnOccupiedCell()) {                        getLocationOnScreen(mTempCell);                        // Send a tap to the wallpaper if the last down was on empty space                        if(lwpSupport)                        mWallpaperManager.sendWallpaperCommand(getWindowToken(),                                "android.wallpaper.tap",                                mTempCell[0] + (int) ev.getX(),                                mTempCell[1] + (int) ev.getY(), 0, null);                    }                }                // Release the drag                clearChildrenCache();                mTouchState = TOUCH_STATE_REST;                mAllowLongPress = false;                break;        }        /*         * The only time we want to intercept motion events is if we are in the         * drag mode.         */        return mTouchState != TOUCH_STATE_REST;    }

The onintercepttouchevent () method and the ontouchevent () method below are mainly used to respond to the messages to be captured when the finger is pressed, such as the stroke speed and the stroke distance. Use the scrollby (int x, int y) method to get the content to be displayed when the slow sliding distance is small. Finally, when the finger is up, the system determines whether to slide one page to the left or one page to the right based on the stroke speed and span, make sure that each user operation ends with a whole sub-view.

 public boolean onTouchEvent(MotionEvent ev) {        //Wysie: If multitouch event is detected        /*if (multiTouchController.onTouchEvent(ev)) {            return false;        }*/        if (mLocked || mLauncher.isAllAppsVisible() || mSensemode) {            return true;        }        if (mVelocityTracker == null) {            mVelocityTracker = VelocityTracker.obtain();        }        mVelocityTracker.addMovement(ev);        final int action = ev.getAction();        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            mLastMotionX = x;            break;        case MotionEvent.ACTION_MOVE:            if (mTouchState == TOUCH_STATE_SCROLLING) {                // Scroll to follow the motion event                final int deltaX = (int) (mLastMotionX - x);                mLastMotionX = x;                if (deltaX < 0) {                    if (mScrollX > -mScrollingBounce) {                        scrollBy(Math.min(deltaX,mScrollingBounce), 0);                        if(lwpSupport)updateWallpaperOffset();                        if(mLauncher.getDesktopIndicator()!=null)mLauncher.getDesktopIndicator().indicate((float)getScrollX()/(float)(getChildCount()*getWidth()));                    }                } else if (deltaX > 0) {                    final int availableToScroll = getChildAt(getChildCount() - 1).getRight() -                            mScrollX - getWidth()+mScrollingBounce;                    if (availableToScroll > 0) {                        scrollBy(deltaX, 0);                        if(lwpSupport)updateWallpaperOffset();                        if(mLauncher.getDesktopIndicator()!=null)mLauncher.getDesktopIndicator().indicate((float)getScrollX()/(float)(getChildCount()*getWidth()));                    }                }            }            break;        case MotionEvent.ACTION_UP:            if (mTouchState == TOUCH_STATE_SCROLLING) {                final VelocityTracker velocityTracker = mVelocityTracker;                velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);                int velocityX = (int) velocityTracker.getXVelocity();                if (velocityX > SNAP_VELOCITY && mCurrentScreen > 0) {                    // Fling hard enough to move left                    snapToScreen(mCurrentScreen - 1);                } else if (velocityX < -SNAP_VELOCITY && mCurrentScreen < getChildCount() - 1) {                    // Fling hard enough to move right                    snapToScreen(mCurrentScreen + 1);                } else {                    snapToDestination();                }                if (mVelocityTracker != null) {                    mVelocityTracker.recycle();                    mVelocityTracker = null;                }            } else if (mTouchState == TOUCH_SWIPE_DOWN_GESTURE )            {            mLauncher.fireSwipeDownAction();            } else if (mTouchState == TOUCH_SWIPE_UP_GESTURE )            {            mLauncher.fireSwipeUpAction();            }            mTouchState = TOUCH_STATE_REST;            break;        case MotionEvent.ACTION_CANCEL:            mTouchState = TOUCH_STATE_REST;        }        return true;    }

The above is the source code for switching between the left and right sliding screens in launcher.

If you have any code, please download http://download.csdn.net/detail/aomandeshangxiao/4063177.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.