Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android編程之Fragment動畫加載方法源碼詳解

Android編程之Fragment動畫加載方法源碼詳解

編輯:關於Android編程

上次談到了Fragment動畫加載的異常問題,今天再聊聊它的動畫加載loadAnimation的實現源代碼:

Animation loadAnimation(Fragment fragment, int transit, boolean enter,
            int transitionStyle) {

接下來具體看一下裡面的源碼部分,我將一部分一部分的講解,首先是:

        Animation animObj = fragment.onCreateAnimation(transit, enter,
                fragment.mNextAnim);
        if (animObj != null) {
            return animObj;
        }
開始的這部分,會調用Fragment的onCreateAnimation這個方法,在Fragment類中,這個方法為空,並沒有現實:
    /**
     * Called when a fragment loads an animation.
     */
    public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
        return null;
    }

如果你寫的Fragment子類在繼承Fragment後重寫了這個方法內容,就可以在這裡面得到動畫。

如果你沒有重寫這個方法,那就會往下繼續:

        if (fragment.mNextAnim != 0) {
            Animation anim = AnimationUtils.loadAnimation(mActivity, fragment.mNextAnim);
            if (anim != null) {
                return anim;
            }
        }
fragment.mNextAnim這個就是在我們添加或者替換fragment的時候,用的FragmentTransaction設置的那個動畫,如上篇文章中後面附的那個例子:

        FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.setCustomAnimations(R.animator.fragment_rotate_enter,
                R.animator.fragment_rotate_exit,
                R.animator.fragment_rotate_pop_enter,
                R.animator.fragment_rotate_pop_exit);
具體是進入動畫,還是退出動畫,就要看當時的具體情況了,這個是不需要開發者操心的。

如果我們之前也沒定義切換動畫,那好吧,就要看我們是否設置transit和transitionStyle參數了:

        if (transit == 0) {
            return null;
        }
        
        int styleIndex = transitToStyleIndex(transit, enter);
        if (styleIndex < 0) {
            return null;
        }
再看一下transitToStyleIndex方法:

    public static int transitToStyleIndex(int transit, boolean enter) {
        int animAttr = -1;
        switch (transit) {
            case FragmentTransaction.TRANSIT_FRAGMENT_OPEN:
                animAttr = enter ? ANIM_STYLE_OPEN_ENTER : ANIM_STYLE_OPEN_EXIT;
                break;
            case FragmentTransaction.TRANSIT_FRAGMENT_CLOSE:
                animAttr = enter ? ANIM_STYLE_CLOSE_ENTER : ANIM_STYLE_CLOSE_EXIT;
                break;
            case FragmentTransaction.TRANSIT_FRAGMENT_FADE:
                animAttr = enter ? ANIM_STYLE_FADE_ENTER : ANIM_STYLE_FADE_EXIT;
                break;
        }
        return animAttr;
    }
所以,transit的值只能是:FragmentTransaction.TRANSIT_FRAGMENT_OPEN,FragmentTransaction.TRANSIT_FRAGMENT_CLOSE,FragmentTransaction.TRANSIT_FRAGMENT_FADE。然後,會根據這個值,調用系統自己的動畫文件:

        switch (styleIndex) {
            case ANIM_STYLE_OPEN_ENTER:
                return makeOpenCloseAnimation(mActivity, 1.125f, 1.0f, 0, 1);
            case ANIM_STYLE_OPEN_EXIT:
                return makeOpenCloseAnimation(mActivity, 1.0f, .975f, 1, 0);
            case ANIM_STYLE_CLOSE_ENTER:
                return makeOpenCloseAnimation(mActivity, .975f, 1.0f, 0, 1);
            case ANIM_STYLE_CLOSE_EXIT:
                return makeOpenCloseAnimation(mActivity, 1.0f, 1.075f, 1, 0);
            case ANIM_STYLE_FADE_ENTER:
                return makeFadeAnimation(mActivity, 0, 1);
            case ANIM_STYLE_FADE_EXIT:
                return makeFadeAnimation(mActivity, 1, 0);
        }


根據之前這些邏輯,代碼運行到這裡,就應該算是結束了。但該方法,後面還有一些代碼:

        if (transitionStyle == 0 && mActivity.getWindow() != null) {
            transitionStyle = mActivity.getWindow().getAttributes().windowAnimations;
        }
        if (transitionStyle == 0) {
            return null;
        }

對比了一樣原始包中的FragmentManager,後面這段代碼在那邊還是有些差異的:
        int styleIndex = transitToStyleIndex(transit, enter);
        if (styleIndex < 0) {
            return null;
        }
        
        if (transitionStyle == 0 && mActivity.getWindow() != null) {
            transitionStyle = mActivity.getWindow().getAttributes().windowAnimations;
        }
        if (transitionStyle == 0) {
            return null;
        }
        
        TypedArray attrs = mActivity.obtainStyledAttributes(transitionStyle,
                com.android.internal.R.styleable.FragmentAnimation);
        int anim = attrs.getResourceId(styleIndex, 0);
        attrs.recycle();
        
        if (anim == 0) {
            return null;
        }
        
        return AnimatorInflater.loadAnimator(mActivity, anim);

所以,transitionStyle這個參數,在V4包這裡是沒有意義的。


好了,Fragment這個動畫加載的方法內容就這些了。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved