1、概述Fragment机制
1、Android3.0引入,可以给大屏幕动态界面设计提供支持。
2、现在主要用在一个页面内嵌多个Tab时使用。
2、Fragment机制原理总结
当前Android最新版本已经是R,Fragment机制也增加了不少改动,复杂了很多,为了单纯了解核心机制,最快的方法可以直接从最初的代码入手。
初版Fragment机制,三个核心类:
1)FragmentManager:
控制Fragment的生命周期,核心是控制Fragment的view状态,比如将fragment中的view添加到Activity中或者将view从Activity中移除,第一版时FragmentManager是放在Activity里的。
2)Fragment:
应用的一个UI片段或行为,可以在Activity中被替换,持有自己的View,定义了自己的生命周期,但是生命周期依赖于依附的Activity的生命周期,当Activity销毁时,Fragment同时也会被销毁。
3)FragmentTransactionImpl(FragmentTransaction的实现类):
对外提供控制Fragment操作的接口,初版只有添加、移除和comit操作,添加和移除只是对添加队列和移除队列操作,commit时委托FragmentManager真正执行操作,设置Fragment的生命周期状态。
初版类图
初版时序图
当前最新的Fragment机制:
为了将Activity和FragmentManager解耦,方便其他地方也可以使用Fragment,比如我们其实可以在service中使用Fragment,虽然场景不是很多。
比如如下博客:
https://blog.csdn.net/mjlong123123/article/details/104156953
4)FragmentController:
FragmentController中的“所有”动作真正执行者都是FragmentHostCallback,绝大部分大部分的动作真正执行者是FragmentHostCallback中的FragmentManager。
5)HostCallbacks(FragmentHostCallback):
为了将FragmentManager于FragmentManager解耦,必须有一个中间类来真正持有FragmentManager对象,这个类就是FragmentHostCallback,Activity中的实现是HostCallbacks,当然,如果我们想要在service中使用Fragment,可以自定义类来继承FragmentHostCallback类来实现。
实际调用链
Activity->FragmentController->FragmentHostCallback->FragmentManager,
BackStackRecord(FragmentTransaction的实现类):第一版时叫FragmentTransactionImpl,对外提供控制Fragment操作的接口,比如添加或移除。
3、细节
P版本Fragment机制
类图
时序图,以下面的代码为例
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
LearnFragment fragment = new LearnFragment();
fragmentTransaction.add(R.id.fragment_contain, fragment);
fragmentTransaction.commit();
}
void moveToState(Fragment f, int newState, int transit, int transitionStyle,
boolean keepActive) {
...
if (f.mState <= newState) {
...
switch (f.mState) {
case Fragment.INITIALIZING:
if (newState > Fragment.INITIALIZING) {
...
f.onAttach(mHost.getContext());
...
if (f.mParentFragment == null) {
mHost.onAttachFragment(f);
}
...
if (!f.mIsCreated) {
...
f.performCreate(f.mSavedFragmentState);
dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
} ...
}
// fall through
case Fragment.CREATED:
...
if (newState > Fragment.CREATED) {
if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f);
if (!f.mFromLayout) {
ViewGroup container = null;
...
f.mView = f.performCreateView(f.performGetLayoutInflater(
f.mSavedFragmentState), container, f.mSavedFragmentState);
if (f.mView != null) {
...
container.addView(f.mView);
...
f.onViewCreated(f.mView, f.mSavedFragmentState);
....
}
}
f.performActivityCreated(f.mSavedFragmentState);
...
}
// fall through
case Fragment.ACTIVITY_CREATED:
...
// fall through
case Fragment.STOPPED:
...
f.performStart();
...
// fall through
case Fragment.STARTED:
...
f.performResume();
...
}
} else if (f.mState > newState) {
switch (f.mState) {
case Fragment.RESUMED:
...
f.performPause();
...
// fall through
case Fragment.STARTED:
...
f.performStop();
...
// fall through
case Fragment.STOPPED:
case Fragment.ACTIVITY_CREATED:
...
f.performDestroyView();
...
f.mContainer.removeView(f.mView);
...
// fall through
case Fragment.CREATED:
...
f.performDestroy();
...
f.performDetach();
...
}
}
...
f.mState = newState;
...
}
FragmentTransaction:是接口类型,实现类在Activity中,为FragmentTransactionImpl
private final class FragmentTransactionImpl implements FragmentTransaction {
ArrayList<Fragment> mAdded;
ArrayList<Fragment> mRemoved;
public FragmentTransaction add(Fragment fragment, int containerViewId) {
return add(fragment, null, containerViewId);
}
public FragmentTransaction add(Fragment fragment, String name, int containerViewId) {
if (fragment.mActivity != null) {
throw new IllegalStateException("Fragment already added: " + fragment);
}
if (name != null) {
fragment.mName = name;
}
if (mRemoved != null) {
mRemoved.remove(fragment);
}
if (mAdded == null) {
mAdded = new ArrayList<Fragment>();
}
fragment.mContainerId = containerViewId;
mAdded.add(fragment);
return this;
}
public FragmentTransaction remove(Fragment fragment) {
if (fragment.mActivity == null) {
throw new IllegalStateException("Fragment not added: " + fragment);
}
if (mAdded != null) {
mAdded.remove(fragment);
}
if (mRemoved == null) {
mRemoved = new ArrayList<Fragment>();
}
mRemoved.add(fragment);
return this;
}
public void commit() {
if (mRemoved != null) {
for (int i=mRemoved.size()-1; i>=0; i--) {
mFragments.removeFragment(mRemoved.get(i));
}
}
if (mAdded != null) {
for (int i=mAdded.size()-1; i>=0; i--) {
mFragments.addFragment(mAdded.get(i));
}
}
if (mFragments != null) {
mFragments.moveToState(mFragments.mCurState);
}
}
}
Activity:
final void performCreate(Bundle icicle) {
onCreate(icicle);
mFragments.dispatchCreate(icicle);
}
final void performStart() {
mCalled = false;
mInstrumentation.callActivityOnStart(this);
。。。
mFragments.dispatchStart();
}
final void performResume() {
performRestart();
。。。
mInstrumentation.callActivityOnResume(this);
。。。
mFragments.dispatchResume();
onPostResume();
。。。
}
final void performPause() {
mFragments.dispatchPause();
onPause();
}
final void performStop() {
。。。
mFragments.dispatchStop();
。。。
mInstrumentation.callActivityOnStop(this);
。。。
}
final void performDestroy() {
mFragments.dispatchDestroy();
onDestroy();
}