LSN10-动态化换肤框架

LSN10-动态化换肤框架

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)

调用及分发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()); // 调用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); // 调用Fragment#performCreate 
                    dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
                } else {
                    f.restoreChildFragmentState(f.mSavedFragmentState);
                    f.mState = Fragment.CREATED;
                }
                f.mRetaining = false;
            }

        case Fragment.CREATED:
            ensureInflatedFragmentView(f);  // 这里是重点,中间会涉及到LayoutInflater的构建

            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);  // 调用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); // 调用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); // 调用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(); //调用Fragment#performStart
                dispatchOnFragmentStarted(f, false);
            }
            // fall through
        case Fragment.STARTED:
            if (newState > Fragment.STARTED) {
                f.performResume();   //调用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(); //调用Fragment#performPause
                dispatchOnFragmentPaused(f, false);
            }
        case Fragment.STARTED:
            if (newState < Fragment.STARTED) {
                f.performStop(); //调用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();  //调用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();  //调用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构建过程

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其实是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);

状态栏及navigatoinbar 换肤

对于字体换肤的小问题

tabLayout 二次进入,字体无法更换的问题
在activity的布局都初始化完成之后,再执行一次更新操作即可

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,829评论 1 331
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,603评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,846评论 0 226
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,600评论 0 191
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,780评论 3 272
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,695评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,136评论 2 293
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,862评论 0 182
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,453评论 0 229
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,942评论 2 233
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,347评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,790评论 2 236
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,293评论 3 221
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,839评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,448评论 0 181
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,564评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,623评论 2 249

推荐阅读更多精彩内容