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í)行一次更新操作即可