LSN10-動態(tài)化換膚框架

LSN10-動態(tài)化換膚框架

fragment源碼分析

androidx.fragment.app.FragmentActivity#onCreateView(android.view.View, java.lang.String, android.content.Context, android.util.AttributeSet)

final View v = dispatchFragmentsOnCreateView(parent, name, context, attrs);
        if (v == null) {
            return super.onCreateView(parent, name, context, attrs);
        }

androidx.fragment.app.FragmentActivity#dispatchFragmentsOnCreateView

mFragments.onCreateView(parent, name, context, attrs);

androidx.fragment.app.FragmentController#onCreateView

mHost.mFragmentManager.onCreateView(parent, name, context, attrs);

androidx.fragment.app.FragmentHostCallback#mFragmentManager

public abstract class FragmentHostCallback<E> extends FragmentContainer {
    final FragmentManagerImpl mFragmentManager = new FragmentManagerImpl();
}

androidx.fragment.app.FragmentManagerImpl#onCreateView(android.view.View, java.lang.String, android.content.Context, android.util.AttributeSet)

Fragment fragment = id != View.NO_ID ? findFragmentById(id) : null;
if (fragment == null && tag != null) {
    fragment = findFragmentByTag(tag);
}
if (fragment == null && containerId != View.NO_ID) {
    fragment = findFragmentById(containerId);
}

if (fragment == null) {
    fragment = mContainer.instantiate(context, fname, null);
    fragment.mFromLayout = true;
    fragment.mFragmentId = id != 0 ? id : containerId;
    fragment.mContainerId = containerId;
    fragment.mTag = tag;
    fragment.mInLayout = true;
    fragment.mFragmentManager = this;
    fragment.mHost = mHost;
    fragment.onInflate(mHost.getContext(), attrs, fragment.mSavedFragmentState);
    addFragment(fragment, true);

}


if (mCurState < Fragment.CREATED && fragment.mFromLayout) {
    moveToState(fragment, Fragment.CREATED, 0, 0, false);
} else {
    moveToState(fragment);
}

if (id != 0) {
    fragment.mView.setId(id);
}
if (fragment.mView.getTag() == null) {
    fragment.mView.setTag(tag);
}

androidx.fragment.app.FragmentManagerImpl#moveToState(androidx.fragment.app.Fragment, int, int, int, boolean)

調(diào)用及分發(fā)fragment生命周期

if ((!f.mAdded || f.mDetached) && newState > Fragment.CREATED) {
    newState = Fragment.CREATED;
}

if (f.mState <= newState) {
    switch (f.mState) {
        case Fragment.INITIALIZING:
            if (newState > Fragment.INITIALIZING) {
                dispatchOnFragmentPreAttached(f, mHost.getContext(), false);
                f.mCalled = false;
                f.onAttach(mHost.getContext()); // 調(diào)用Fragment#onAttach 
                
                if (f.mParentFragment == null) {
                    mHost.onAttachFragment(f);
                } else {
                    f.mParentFragment.onAttachFragment(f);
                }
                dispatchOnFragmentAttached(f, mHost.getContext(), false);

                if (!f.mIsCreated) {
                    dispatchOnFragmentPreCreated(f, f.mSavedFragmentState, false);
                    f.performCreate(f.mSavedFragmentState); // 調(diào)用Fragment#performCreate 
                    dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
                } else {
                    f.restoreChildFragmentState(f.mSavedFragmentState);
                    f.mState = Fragment.CREATED;
                }
                f.mRetaining = false;
            }

        case Fragment.CREATED:
            ensureInflatedFragmentView(f);  // 這里是重點(diǎn)溉躲,中間會涉及到LayoutInflater的構(gòu)建

            if (newState > Fragment.CREATED) {
                if (!f.mFromLayout) {
                    ViewGroup container = null;
                    if (f.mContainerId != 0) {
                        container = (ViewGroup) mContainer.onFindViewById(f.mContainerId);
                        if (container == null && !f.mRestored) {
                            String resName;
                            try {
                                resName = f.getResources().getResourceName(f.mContainerId);
                            } catch (NotFoundException e) {
                                resName = "unknown";
                            }

                        }
                    }
                    f.mContainer = container;
                    f.performCreateView(f.performGetLayoutInflater(
                            f.mSavedFragmentState), container, f.mSavedFragmentState);  // 調(diào)用Fragment#performCreateView 
                    if (f.mView != null) {
                        f.mInnerView = f.mView;
                        f.mView.setSaveFromParentEnabled(false);
                        if (container != null) {
                            container.addView(f.mView);
                        }
                        if (f.mHidden) {
                            f.mView.setVisibility(View.GONE);
                        }
                        f.onViewCreated(f.mView, f.mSavedFragmentState); // 調(diào)用Fragment#onViewCreated
                        dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState,
                                false);
                        // dispatchOnFragmentViewCreated in case visibility is changed
                        f.mIsNewlyAdded = (f.mView.getVisibility() == View.VISIBLE)
                                && f.mContainer != null;
                    } else {
                        f.mInnerView = null;
                    }
                }

                f.performActivityCreated(f.mSavedFragmentState); // 調(diào)用Fragment#performActivityCreated
                dispatchOnFragmentActivityCreated(f, f.mSavedFragmentState, false);
                if (f.mView != null) {
                    f.restoreViewState(f.mSavedFragmentState);
                }
                f.mSavedFragmentState = null;
            }
            // fall through
        case Fragment.ACTIVITY_CREATED:
            if (newState > Fragment.ACTIVITY_CREATED) {
                f.performStart(); //調(diào)用Fragment#performStart
                dispatchOnFragmentStarted(f, false);
            }
            // fall through
        case Fragment.STARTED:
            if (newState > Fragment.STARTED) {
                f.performResume();   //調(diào)用Fragment#performResume
                dispatchOnFragmentResumed(f, false);
                f.mSavedFragmentState = null;
                f.mSavedViewState = null;
            }
    }
} else if (f.mState > newState) {
    switch (f.mState) {
        case Fragment.RESUMED:
            if (newState < Fragment.RESUMED) {
                f.performPause(); //調(diào)用Fragment#performPause
                dispatchOnFragmentPaused(f, false);
            }
        case Fragment.STARTED:
            if (newState < Fragment.STARTED) {
                f.performStop(); //調(diào)用Fragment#performStop
                dispatchOnFragmentStopped(f, false);
            }

        case Fragment.ACTIVITY_CREATED:
            if (newState < Fragment.ACTIVITY_CREATED) {
                if (DEBUG) Log.v(TAG, "movefrom ACTIVITY_CREATED: " + f);
                if (f.mView != null) {
                    if (mHost.onShouldSaveFragmentState(f) && f.mSavedViewState == null) {
                        saveFragmentViewState(f);
                    }
                }
                f.performDestroyView();  //調(diào)用Fragment#performDestroyView
                dispatchOnFragmentViewDestroyed(f, false);
                if (f.mView != null && f.mContainer != null) {
                    f.mContainer.endViewTransition(f.mView);
                    f.mView.clearAnimation();
                    AnimationOrAnimator anim = null;
                    if (mCurState > Fragment.INITIALIZING && !mDestroyed
                            && f.mView.getVisibility() == View.VISIBLE
                            && f.mPostponedAlpha >= 0) {
                        anim = loadAnimation(f, transit, false,
                                transitionStyle);
                    }
                    f.mPostponedAlpha = 0;
                    if (anim != null) {
                        animateRemoveFragment(f, anim, newState);
                    }
                    f.mContainer.removeView(f.mView);
                }
                f.mContainer = null;
                f.mView = null;
                f.mViewLifecycleOwner = null;
                f.mViewLifecycleOwnerLiveData.setValue(null);
                f.mInnerView = null;
                f.mInLayout = false;
            }
            // fall through
        case Fragment.CREATED:
            if (newState < Fragment.CREATED) {
                if (mDestroyed) {
                    if (f.getAnimatingAway() != null) {
                        View v = f.getAnimatingAway();
                        f.setAnimatingAway(null);
                        v.clearAnimation();
                    } else if (f.getAnimator() != null) {
                        Animator animator = f.getAnimator();
                        f.setAnimator(null);
                        animator.cancel();
                    }
                }
                if (f.getAnimatingAway() != null || f.getAnimator() != null) {
                    f.setStateAfterAnimating(newState);
                    newState = Fragment.CREATED;
                } else {
                    if (!f.mRetaining) {
                        f.performDestroy();
                        dispatchOnFragmentDestroyed(f, false);
                    } else {
                        f.mState = Fragment.INITIALIZING;
                    }

                    f.performDetach();  //調(diào)用Fragment#performDetach
                    dispatchOnFragmentDetached(f, false);
                    if (!keepActive) {
                        if (!f.mRetaining) {
                            makeInactive(f);
                        } else {
                            f.mHost = null;
                            f.mParentFragment = null;
                            f.mFragmentManager = null;
                        }
                    }
                }
            }
    }
}

if (f.mState != newState) {
    f.mState = newState;
}

/fragment/app/FragmentManager.java:1460

 f.performCreateView(
     f.performGetLayoutInflater(
         f.mSavedFragmentState), container,.mSavedFragmentState);

Fragment LayoutInflater構(gòu)建過程

androidx.fragment.app.Fragment#performGetLayoutInflater

androidx.fragment.app.Fragment#getLayoutInflater(android.os.Bundle)

Fragment換膚 (需要重新整理)

android.support.v4.app.Fragment#getLayoutInflater(android.os.Bundle)

LayoutInflater result = mHost.onGetLayoutInflater(); // 這里的LayoutInflater其實(shí)是PhoneLayoutInflater
getChildFragmentManager();
LayoutInflaterCompat.setFactory2(result, mChildFragmentManager.getLayoutInflaterFactory());

android.support.v4.app.FragmentHostCallback#onGetLayoutInflater

(LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

android.app.ContextImpl#getSystemService

SystemServiceRegistry.getSystemService(this, name);

android.app.SystemServiceRegistry#getSystemServiceName

SYSTEM_SERVICE_NAMES.get(serviceClass);

app/SystemServiceRegistry.java:174

registerService(
    Context.LAYOUT_INFLATER_SERVICE, LayoutInflater.class,
    new CachedServiceFetcher<LayoutInflater>() {
        @Override
        public LayoutInflater createService(ContextImpl ctx) {
            return new PhoneLayoutInflater(ctx.getOuterContext());
        }});

android.support.v4.app.Fragment#getChildFragmentManager

if (mChildFragmentManager == null) {
    instantiateChildFragmentManager(); // 初始化FragmentManager
    if (mState >= RESUMED) {
        mChildFragmentManager.dispatchResume();
    } else if (mState >= STARTED) {
        mChildFragmentManager.dispatchStart();
    } else if (mState >= ACTIVITY_CREATED) {
     mChildFragmentManager.dispatchActivityCreated();
    } else if (mState >= CREATED) {
        mChildFragmentManager.dispatchCreate();
    }
}

android.support.v4.app.Fragment#instantiateChildFragmentManager

mChildFragmentManager = new FragmentManagerImpl();
mChildFragmentManager.attachController(mHost, new FragmentContainer() {
    @Override
    @Nullable
    public View onFindViewById(int id) {
        if (mView == null) {
            throw new IllegalStateException("Fragment does not have a view");
        }
        return mView.findViewById(id);
    }

    @Override
    public boolean onHasView() {
        return (mView != null);
    }

    @Override
    public Fragment instantiate(Context context, String className, Bundle arguments) {
        return mHost.instantiate(context, className, arguments);
    }
}, this);

android.support.v4.app.FragmentManagerImpl

final class FragmentManagerImpl extends FragmentManager implements LayoutInflater.Factory2 {}

androidx.fragment.app.FragmentActivity.HostCallbacks

androidx.fragment.app.FragmentActivity.HostCallbacks#onGetLayoutInflater

FragmentActivity.this.getLayoutInflater().cloneInContext(FragmentActivity.this);

狀態(tài)欄及navigatoinbar 換膚

對于字體換膚的小問題

tabLayout 二次進(jìn)入,字體無法更換的問題
在activity的布局都初始化完成之后赴穗,再執(zhí)行一次更新操作即可

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末硫兰,一起剝皮案震驚了整個(gè)濱河市辽话,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖驰弄,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件遮糖,死亡現(xiàn)場離奇詭異绣的,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)欲账,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門屡江,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人赛不,你說我怎么就攤上這事惩嘉。” “怎么了踢故?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵文黎,是天一觀的道長。 經(jīng)常有香客問我畴椰,道長臊诊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任斜脂,我火速辦了婚禮抓艳,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘帚戳。我一直安慰自己玷或,他們只是感情好儡首,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著偏友,像睡著了一般蔬胯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上位他,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天氛濒,我揣著相機(jī)與錄音,去河邊找鬼鹅髓。 笑死舞竿,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的窿冯。 我是一名探鬼主播骗奖,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼醒串!你這毒婦竟也來了执桌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤芜赌,失蹤者是張志新(化名)和其女友劉穎仰挣,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體较鼓,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡椎木,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了博烂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片香椎。...
    茶點(diǎn)故事閱讀 39,991評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖禽篱,靈堂內(nèi)的尸體忽然破棺而出畜伐,到底是詐尸還是另有隱情,我是刑警寧澤躺率,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布玛界,位于F島的核電站,受9級特大地震影響悼吱,放射性物質(zhì)發(fā)生泄漏慎框。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一后添、第九天 我趴在偏房一處隱蔽的房頂上張望笨枯。 院中可真熱鬧,春花似錦、人聲如沸馅精。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽洲敢。三九已至漫玄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間压彭,已是汗流浹背睦优。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留哮塞,地道東北人刨秆。 一個(gè)月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓凳谦,卻偏偏與公主長得像忆畅,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子尸执,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容