CanPHP框架技术讨论

导航

 

1.桌面的显示会调用:showWorkspace(true)

 void showWorkspace(boolean animated) {
        Resources res = getResources();
        int stagger = res.getInteger(R.integer.config_appsCustomizeWorkspaceAnimationStagger);

        mWorkspace.changeState(Workspace.State.NORMAL, animated, stagger);
        if (mState == State.APPS_CUSTOMIZE) {
            closeAllApps(animated);
        }

        // Change the state *after* we've called all the transition code
        mState = State.WORKSPACE;

        // Resume the auto-advance of widgets
        mUserPresent = true;
        updateRunning();

        // send an accessibility event to announce the context change
        getWindow().getDecorView().sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
    }

2.以上代码分析得到,调用了Workspace类中的changeState函数,从字面上看,貌似是状态的改变,进入此类找方法。

    public void changeState(State shrinkState) {
        changeState(shrinkState, true);
    }

    void changeState(final State state, boolean animated) {
        changeState(state, animated, 0);
    }

    void changeState(final State state, boolean animated, int delay) {
        if (mFirstLayout) {
            // (mFirstLayout == "first layout has not happened yet")
            // cancel any pending shrinks that were set earlier
            mSwitchStateAfterFirstLayout = false;
            mStateAfterFirstLayout = state;
            return;
        }

        if (mAnimator != null) {
            mAnimator.cancel();
        }

        // Stop any scrolling, move to the current page right away
        setCurrentPage((mNextPage != INVALID_PAGE) ? mNextPage : mCurrentPage);

        float finalScaleFactor = 1.0f;
        float finalBackgroundAlpha = (state == State.SPRING_LOADED) ? 1.0f : 0f;
        boolean normalState = false;
        State oldState = mState;
        mState = state;
        boolean zoomIn = true;

        if (state != State.NORMAL) {
            finalScaleFactor = mSpringLoadedShrinkFactor - (state == State.SMALL ? 0.1f : 0);
            if (oldState == State.NORMAL && state == State.SMALL) {
                zoomIn = false;
                if (animated) {
                    hideScrollingIndicator(true);
                }
                setLayoutScale(finalScaleFactor);
                updateChildrenLayersEnabled();
            } else {
                finalBackgroundAlpha = 1.0f;
                setLayoutScale(finalScaleFactor);
            }
        } else {
            setLayoutScale(1.0f);
            normalState = true;
        }

        float translationX = 0;
        float translationY = 0;

        mAnimator = new AnimatorSet();

        final int screenCount = getChildCount();
        initAnimationArrays();

        final int duration = zoomIn ? 
                getResources().getInteger(R.integer.config_workspaceUnshrinkTime) :
                getResources().getInteger(R.integer.config_appsCustomizeWorkspaceShrinkTime);
        for (int i = 0; i < screenCount; i++) {
            final CellLayout cl = (CellLayout)getChildAt(i);
            float finalAlphaValue = 0f;
            float rotation = 0f;

            // Set the final alpha depending on whether we are fading side pages.  On phone ui,
            // we don't do any of the rotation, or the fading alpha in portrait.  See the
            // ctor and screenScrolled().
            if (mFadeInAdjacentScreens && normalState) {
                finalAlphaValue = (i == mCurrentPage) ? 1f : 0f;
            } else {
                finalAlphaValue = 1f;
            }

            if (LauncherApplication.isScreenLarge()) {
                if (i < mCurrentPage) {
                    rotation = WORKSPACE_ROTATION;
                } else if (i > mCurrentPage) {
                    rotation = -WORKSPACE_ROTATION;
                }
            }

            float finalAlphaMultiplierValue = 1f;
            // If the screen is not xlarge, then don't rotate the CellLayouts
            // NOTE: If we don't update the side pages alpha, then we should not hide the side
            //       pages. see unshrink().
            if (LauncherApplication.isScreenLarge()) {
                translationX = getOffsetXForRotation(rotation, cl.getWidth(), cl.getHeight());
            }

            mOldAlphas[i] = cl.getAlpha();
            mNewAlphas[i] = finalAlphaValue;
            if (animated) {
                mOldTranslationXs[i] = cl.getTranslationX();
                mOldTranslationYs[i] = cl.getTranslationY();
                mOldScaleXs[i] = cl.getScaleX();
                mOldScaleYs[i] = cl.getScaleY();
                mOldBackgroundAlphas[i] = cl.getBackgroundAlpha();
                mOldBackgroundAlphaMultipliers[i] = cl.getBackgroundAlphaMultiplier();
                mOldRotationYs[i] = cl.getRotationY();

                mNewTranslationXs[i] = translationX;
                mNewTranslationYs[i] = translationY;
                mNewScaleXs[i] = finalScaleFactor;
                mNewScaleYs[i] = finalScaleFactor;
                mNewBackgroundAlphas[i] = finalBackgroundAlpha;
                mNewBackgroundAlphaMultipliers[i] = finalAlphaMultiplierValue;
                mNewRotationYs[i] = rotation;
            } else {
                cl.setTranslationX(translationX);
                cl.setTranslationY(translationY);
                cl.setScaleX(finalScaleFactor);
                cl.setScaleY(finalScaleFactor);
                cl.setBackgroundAlpha(0.0f);
                cl.setBackgroundAlphaMultiplier(finalAlphaMultiplierValue);
                cl.setAlpha(finalAlphaValue);
                cl.setRotationY(rotation);
                mChangeStateAnimationListener.onAnimationEnd(null);
            }
        }

        if (animated) {
            ValueAnimator animWithInterpolator =
                ValueAnimator.ofFloat(0f, 1f).setDuration(duration);

            if (zoomIn) {
                animWithInterpolator.setInterpolator(mZoomInInterpolator);
            }

            animWithInterpolator.addUpdateListener(new LauncherAnimatorUpdateListener() {
                public void onAnimationUpdate(float a, float b) {
                    mTransitionProgress = b;
                    if (b == 0f) {
                        // an optimization, but not required
                        return;
                    }
                    invalidate();
                    for (int i = 0; i < screenCount; i++) {
                        final CellLayout cl = (CellLayout) getChildAt(i);
                        cl.fastInvalidate();
                        cl.setFastTranslationX(a * mOldTranslationXs[i] + b * mNewTranslationXs[i]);
                        cl.setFastTranslationY(a * mOldTranslationYs[i] + b * mNewTranslationYs[i]);
                        cl.setFastScaleX(a * mOldScaleXs[i] + b * mNewScaleXs[i]);
                        cl.setFastScaleY(a * mOldScaleYs[i] + b * mNewScaleYs[i]);
                        cl.setFastBackgroundAlpha(
                                a * mOldBackgroundAlphas[i] + b * mNewBackgroundAlphas[i]);
                        cl.setBackgroundAlphaMultiplier(a * mOldBackgroundAlphaMultipliers[i] +
                                b * mNewBackgroundAlphaMultipliers[i]);
                        cl.setFastAlpha(a * mOldAlphas[i] + b * mNewAlphas[i]);
                    }
                }
            });

            ValueAnimator rotationAnim =
                ValueAnimator.ofFloat(0f, 1f).setDuration(duration);
            rotationAnim.setInterpolator(new DecelerateInterpolator(2.0f));
            rotationAnim.addUpdateListener(new LauncherAnimatorUpdateListener() {
                public void onAnimationUpdate(float a, float b) {
                    if (b == 0f) {
                        // an optimization, but not required
                        return;
                    }
                    for (int i = 0; i < screenCount; i++) {
                        final CellLayout cl = (CellLayout) getChildAt(i);
                        cl.setFastRotationY(a * mOldRotationYs[i] + b * mNewRotationYs[i]);
                    }
                }
            });
            mAnimator.playTogether(animWithInterpolator, rotationAnim);
            mAnimator.setStartDelay(delay);
            // If we call this when we're not animated, onAnimationEnd is never called on
            // the listener; make sure we only use the listener when we're actually animating
            mAnimator.addListener(mChangeStateAnimationListener);
            mAnimator.start();
        }

        if (state == State.SPRING_LOADED) {
            // Right now we're covered by Apps Customize
            // Show the background gradient immediately, so the gradient will
            // be showing once AppsCustomize disappears
            animateBackgroundGradient(getResources().getInteger(
                    R.integer.config_appsCustomizeSpringLoadedBgAlpha) / 100f, false);
        } else {
            // Fade the background gradient away
            animateBackgroundGradient(0f, true);
        }
    }

3.从以上代码分析得到这个只是得到了动画的显示,那么说明数据的填充已经在前面完成了,再到回去分析。

4.进入Launcher类看到setupViews() ,找到 mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);我就猜想一下,是不是找到元素后,对其子元素就进行了填充呢?

5.查找到这里

 View createShortcut(ShortcutInfo info) {
        return createShortcut(R.layout.application,
                (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);
    }

就能猜测到数据应该就是在这里添加的。

6.查找此方法就发现这个方法:

public void bindItems(ArrayList<ItemInfo> shortcuts, int start, int end) {
        setLoadOnResume();

        final Workspace workspace = mWorkspace;
        for (int i=start; i<end; i++) {
            final ItemInfo item = shortcuts.get(i);

            // Short circuit if we are loading dock items for a configuration which has no dock
            if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
                continue;
            }

            switch (item.itemType) {
                case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
                case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
                    View shortcut = createShortcut((ShortcutInfo)item);
                    workspace.addInScreen(shortcut, item.container, item.screen, item.cellX,
                            item.cellY, 1, 1, false);
                    break;
                case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
                    FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,
                            (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),
                            (FolderInfo) item, mIconCache);
                    workspace.addInScreen(newFolder, item.container, item.screen, item.cellX,
                            item.cellY, 1, 1, false);
                    break;
            }
        }
        workspace.requestLayout();
    }

7.原来这个binditem是一个launchermodel的回调函数,再添加数据到model的时候,会进行回调进行数据绑定。

8.基本上流程已经通顺了!

posted on 2012-11-29 14:37  創丗仼  阅读(1970)  评论(0编辑  收藏  举报