Fragment狀態分爲 INITIALIZING、CREATED、ACTIVITY_CREATED、 STOPPED、STARTED、RESUMED共6個狀態。預期狀態(newState)大於Fragment自身的狀態(f.mState < newState)則將Fragment的狀態向前推進對應Fragment的創建過程;預期狀態(newState)小於Fragment自身的狀態(f.mState > newState)則將Fragment的狀態向後推進對應Fragment的銷燬過程。
不帶Fragment參數的moveToSate方法是將FragmentManager下面的所有Fragment狀態轉移到當前FragmentManager的狀態,該方法內部會調用帶Fragment參數的moveToState方法。FragmentActivity會間接的調用不帶Fragment參數的moveToState方法主要是用於設置當前的FragmentManager的狀態。
帶Fragment參數的moveToState方法是將參數中的Fragment狀態轉移到當前FragmentManager的狀態。FragmentManager的detachFragment、attachFragment、removeFragment、addFragment等方法不會在FragmentActivity中出現,但是會在FragmentTransaction中的run方法中出現,表明每次提交的事務最終會通過調用這些方法完成實際的Fragment的加載與銷燬。
一個佈局中嵌套多個Fragment範例(平板電腦)
res/layout/fragment_items_list.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android:id="@+id/lvItems"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
</ListView>
</RelativeLayout>
public class ItemsListFragment extends Fragment {
private ArrayAdapter<Item> adapterItems; //Item是自定義的一類數據
private ListView lvItems;
private OnListItemSelectedListener listener;
public interface OnListItemSelectedListener { public void onItemSelected(Item item); }
//自定義接口,用於回調實現該接口的Activity相關方法
@Override public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof OnListItemSelectedListener) {
listener = (OnListItemSelectedListener) activity;
} else {
throw new ClassCastException(
activity.toString() + " must implement ItemsListFragment.OnListItemSelectedListener");
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ArrayList<Item> items = Item.getItems();
adapterItems = new ArrayAdapter<Item>(getActivity(), android.R.layout.simple_list_item_activated_1, items);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_items_list, container, false);
lvItems = (ListView) view.findViewById(R.id.lvItems);
lvItems.setAdapter(adapterItems);
lvItems.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View item, int position, long rowId) {
Item item = adapterItems.getItem(position);
listener.onItemSelected(item);
}
});
return view;
}
public void setActivateOnItemClick(boolean activateOnItemClick) {
lvItems.setChoiceMode(
activateOnItemClick ? ListView.CHOICE_MODE_SINGLE
: ListView.CHOICE_MODE_NONE);
}
}
res/layout/fragment_item_detail.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/tvTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="Item Title"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/tvBody"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tvTitle"
android:layout_centerHorizontal="true"
android:layout_marginTop="19dp"
android:text="Item Body" />
</RelativeLayout>
public class ItemDetailFragment extends Fragment {
private Item item;
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
item = (Item) getArguments().getSerializable("item"); //之前通過調用Fragment的setArguments方法傳進來的bundle數據
}
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_item_detail, container, false);
TextView tvTitle = (TextView) view.findViewById(R.id.tvTitle);
TextView tvBody = (TextView) view.findViewById(R.id.tvBody);
tvTitle.setText(item.getTitle());
tvBody.setText(item.getBody());
return view;
}
public static ItemDetailFragment newInstance(Item item) {
ItemDetailFragment fragmentDemo = new ItemDetailFragment();
Bundle args = new Bundle();
args.putSerializable("item", item);
fragmentDemo.setArguments(args); //getArguments().getSerializable("item")獲取該數據
return fragmentDemo;
}
}
res/layout/activity_items_list.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".ItemsListActivity" >
<fragment
android:id="@+id/fragmentItemsList"
android:name="com.codepath.example.masterdetaildemo.ItemsListFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
tools:layout="@layout/fragment_items_list" />
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:showDividers="middle"
android:baselineAligned="false"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
android:id="@+id/fragmentItemsList"
android:name="com.codepath.example.masterdetaildemo.ItemsListFragment"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
tools:layout="@layout/fragment_items_list" />
<View android:background="#000000"
android:layout_width="1dp"
android:layout_height="wrap_content"
/>
<FrameLayout
android:id="@+id/flDetailContainer"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3" />
</LinearLayout>
public class ItemsListActivity extends AppCompatActivity implements OnItemSelectedListener {
private boolean isTwoPane = false; //平板標誌位
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_items_list);
determinePaneLayout(); //判斷當前使用的是哪個Layout文件
}
private void determinePaneLayout() {
FrameLayout fragmentItemDetail = (FrameLayout) findViewById(R.id.flDetailContainer); //能夠獲取到FrameLayout表明使用的平板佈局
if (fragmentItemDetail != null) {
isTwoPane = true;
ItemsListFragment fragmentItemsList = (ItemsListFragment) getSupportFragmentManager()
.findFragmentById(R.id.fragmentItemsList);
//因爲ItemsListFragment實在平板佈局文件中寫死的因此可以直接獲取到該Fragment,而不需要使用事務(FragmentTransaction)
fragmentItemsList.setActivateOnItemClick(true);
}
}
@Override public void onItemSelected(Item item) {
if (isTwoPane) {
ItemDetailFragment fragmentItem = ItemDetailFragment.newInstance(item);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.flDetailContainer, fragmentItem);
ft.commit();
} else {
Intent i = new Intent(this, ItemDetailActivity.class);
i.putExtra("item", item);
startActivity(i);
}
}
}
public class ItemDetailActivity extends AppCompatActivity {
ItemDetailFragment fragmentItemDetail;
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_item_detail);
Item item = (Item) getIntent().getSerializableExtra("item");
if (savedInstanceState == null) {
fragmentItemDetail = ItemDetailFragment.newInstance(item);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.flDetailContainer, fragmentItemDetail);
ft.commit();
}
}
}
res/layout/activity_item_detail.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/flDetailContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".ItemDetailActivity" >
</FrameLayout>
源碼分析
FragmentActivity.class
final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
public FragmentManager getSupportFragmentManager() {
return mFragments.getSupportFragmentManager();
}
protected void onCreate(@Nullable Bundle savedInstanceState) {
mFragments.attachHost(null /*parent*/);
//該方法其最終目的實則是爲了將FragmentController中的HostCallback對象引用傳給FragmentManager,具體分析看FragmentController
super.onCreate(savedInstanceState);
NonConfigurationInstances nc = (NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) { mFragments.restoreLoaderNonConfig(nc.loaders); }
if (savedInstanceState != null) {
Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
mFragments.restoreAllState(p, nc != null ? nc.fragments : null);
}
mFragments.dispatchCreate();
//該方法最底層會調用FragmentManager的同名方法,對具體的Fragment進行操作
}
@Override protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Parcelable p = mFragments.saveAllState();
if (p != null) {
outState.putParcelable(FRAGMENTS_TAG, p); //存儲當前Fragment保存的FragmentController的狀態
}
}
FragmentController.class
public static final FragmentController createController(FragmentHostCallback<?> callbacks) {
return new FragmentController(callbacks);
}
private FragmentController(FragmentHostCallback<?> callbacks) {
mHost = callbacks;
}
public FragmentManager getSupportFragmentManager() {
return mHost.getFragmentManagerImpl();
}
public void attachHost(Fragment parent) {
mHost.mFragmentManager.attachController( mHost, mHost /*container*/, parent);
}
public void dispatchCreate() {
mHost.mFragmentManager.dispatchCreate();
}
[email protected]
public HostCallbacks() {
super(FragmentActivity.this /*fragmentActivity*/);
}
FragmentHostCallback.class
private final Activity mActivity;
final Context mContext;
private final Handler mHandler;
final FragmentManagerImpl mFragmentManager = new FragmentManagerImpl();
FragmentHostCallback(FragmentActivity activity) {
this(activity, activity /*context*/, activity.mHandler, 0 /*windowAnimations*/);
}
FragmentHostCallback(Activity activity, Context context, Handler handler, int windowAnimations) {
mActivity = activity;
mContext = context;
mHandler = handler;
mWindowAnimations = windowAnimations;
}
FragmentManagerImpl getFragmentManagerImpl() {
return mFragmentManager;
}
Fragment.class
static final Object USE_DEFAULT_TRANSITION = new Object();
static final int INITIALIZING = 0; // Not yet created.
static final int CREATED = 1; // Created.
static final int ACTIVITY_CREATED = 2; // The activity has finished its creation.
static final int STOPPED = 3; // Fully created, not started.
static final int STARTED = 4; // Created and started, not resumed.
static final int RESUMED = 5; // Created started and resumed.
int mState = INITIALIZING;
int mContainerId; //當前Fragment所屬的ViewGroup對應的id號
ViewGroup mContainer;
View mView;
View mInnerView;
String mTag; //當前Fragment的標籤
Fragment mParentFragment;
FragmentManagerImpl mChildFragmentManager;
FragmentManagerImpl mFragmentManager;
boolean mFromLayout; //當前Fragment來自於一個Layout
boolean mInLayout; //view has actually been inflated in its layout
boolean mResumed;
boolean mDetached; //當前Fragment是否和context已經綁定
boolean mAdded; //當前Fragment是否被存儲在FragmentManager的mAdded集合集合中
boolean mRemoving; //當前Fragment已經存在FragmentManager中則該值爲false
void initState() {
mIndex = -1;
mWho = null;
mAdded = false;
mRemoving = false;
mResumed = false;
mFromLayout = false;
mInLayout = false;
mRestored = false;
mBackStackNesting = 0;
mFragmentManager = null;
mChildFragmentManager = null;
mHost = null;
mFragmentId = 0;
mContainerId = 0;
mTag = null;
mHidden = false;
mDetached = false;
mRetaining = false;
mLoaderManager = null;
mLoadersStarted = false;
mCheckedForLoaderManager = false;
}
BackStackRecord.class (FragmentTransaction)
final FragmentManagerImpl mManager;
Op mHead;
Op mTail;
int mNumOp;
static final class Op {
Op next;
Op prev;
int cmd;
Fragment fragment;
......
ArrayList<Fragment> removed;
}
public BackStackRecord(FragmentManagerImpl manager) {
mManager = manager;
}
public FragmentTransaction add(int containerViewId, Fragment fragment) {
doAddOp(containerViewId, fragment, null, OP_ADD);
return this;
}
private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) {
fragment.mFragmentManager = mManager;
if (tag != null) {
if (fragment.mTag != null && !tag.equals(fragment.mTag)) {
throw new IllegalStateException("Can't change tag of fragment " + fragment + ": was " + fragment.mTag + " now " + tag);
}
fragment.mTag = tag;
} //不能改變標籤
if (containerViewId != 0) {
if (fragment.mFragmentId != 0 && fragment.mFragmentId != containerViewId) {
throw new IllegalStateException("Can't change container ID of fragment " + fragment + ": was " + fragment.mFragmentId + " now " + containerViewId);
}
fragment.mContainerId = fragment.mFragmentId = containerViewId;
} //不能改變Fragment所屬ViewGroup
Op op = new Op();
op.cmd = opcmd;
op.fragment = fragment;
addOp(op);
}
void addOp(Op op) {
if (mHead == null) { mHead = mTail = op; }
else {
op.prev = mTail;
mTail.next = op;
mTail = op;
}
.....
mNumOp++;
}
public int commit() {
return commitInternal(false);
}
int commitInternal(boolean allowStateLoss) {
if (mCommitted) throw new IllegalStateException("commit already called");
mCommitted = true;
if (mAddToBackStack) { mIndex = mManager.allocBackStackIndex(this);} //默認是false
else { mIndex = -1; }
mManager.enqueueAction(this, allowStateLoss); //note1
return mIndex;
}
public void run() {
...
TransitionState state = null;
SparseArray<Fragment> firstOutFragments = null;
SparseArray<Fragment> lastInFragments = null;
if (SUPPORTS_TRANSITIONS) { //當前版本大於21,Build.VERSION.SDK_INT >= 21則執行下面代碼
firstOutFragments = new SparseArray<Fragment>();
lastInFragments = new SparseArray<Fragment>();
calculateFragments(firstOutFragments, lastInFragments);
//Finds the first removed fragment and last added fragments when going forward
state = beginTransition(firstOutFragments, lastInFragments, false);
}
int transitionStyle = state != null ? 0 : mTransitionStyle;
int transition = state != null ? 0 : mTransition;
Op op = mHead; //note1
while (op != null) {
......
switch (op.cmd) {
case OP_ADD: { //note2
Fragment f = op.fragment;
......
mManager.addFragment(f, false);
} break;
case OP_REPLACE: {
Fragment f = op.fragment;
int containerId = f.mContainerId;
if (mManager.mAdded != null) {
for (int i=0; i<mManager.mAdded.size(); i++) {
Fragment old = mManager.mAdded.get(i);
if (old.mContainerId == containerId) {
if (old == f) { op.fragment = f = null; }
else {
if (op.removed == null) { op.removed = new ArrayList<Fragment>(); }
op.removed.add(old); //存入op的鏈表中
old.mNextAnim = exitAnim;
......
mManager.removeFragment(old, transition, transitionStyle);
} //end of else
} //end of if (old.mContainerId == containerId)
} end of for
} end of if (mManager.mAdded != null)
if (f != null) {//證明當前的Fragment在FragmentManager的mAdded數組中不存在,需要添加到該數組中
......
mManager.addFragment(f, false);
}
} break;
case OP_REMOVE: {
Fragment f = op.fragment;
......
mManager.removeFragment(f, transition, transitionStyle); //後面的兩個參數在分析的時候爲簡單起見,全部看成爲0
} break;
case OP_HIDE: {
Fragment f = op.fragment;
......
mManager.hideFragment(f, transition, transitionStyle);
} break;
case OP_SHOW: {
Fragment f = op.fragment;
......
mManager.showFragment(f, transition, transitionStyle);
} break;
case OP_DETACH: {
Fragment f = op.fragment;
......
mManager.detachFragment(f, transition, transitionStyle);
} break;
case OP_ATTACH: {
Fragment f = op.fragment;
......
mManager.attachFragment(f, transition, transitionStyle);
} break;
default: { throw new IllegalArgumentException("Unknown cmd: " + op.cmd); }
}// end of switch
op = op.next;
} //end of while
mManager.moveToState(mManager.mCurState, transition, transitionStyle, true);
.....
}
FragmentManagerImpl.class(FragmentManager)
ArrayList<Fragment> mActive;
ArrayList<Fragment> mAdded;
ArrayList<BackStackRecord> mBackStack;
boolean mDestroyed;
FragmentHostCallback mHost;
//提供主線程的Handler,FragmentManagerImpl所屬的Activity,在FragmentActivity的onCreate方法中會對其進行初始化
ArrayList<Runnable> mPendingActions; //需要執行的異步事務
boolean mNeedMenuInvalidate; //當前Fragment需要菜單欄
int mCurState = Fragment.INITIALIZING;//當前FragmentManager下的所有Fragment應該到達的狀態
public void attachController(FragmentHostCallback host, FragmentContainer container, Fragment parent) {
if (mHost != null) throw new IllegalStateException("Already attached");
mHost = host;
mContainer = container;
mParent = parent;
}
public FragmentTransaction beginTransaction() {
return new BackStackRecord(this);
}
public void enqueueAction(Runnable action, boolean allowStateLoss) {
if (!allowStateLoss) { checkStateLoss(); }
synchronized (this) {
if (mDestroyed || mHost == null) { throw new IllegalStateException("Activity has been destroyed"); }
if (mPendingActions == null) { mPendingActions = new ArrayList<Runnable>(); }
mPendingActions.add(action);
if (mPendingActions.size() == 1) {
mHost.getHandler().removeCallbacks(mExecCommit);
mHost.getHandler().post(mExecCommit);
}
}
}
Runnable mExecCommit = new Runnable() {
@Override
public void run() { execPendingActions(); } //該方法內部就會將mPendingActions中的action順序調用run方法執行
};
public void addFragment(Fragment fragment, boolean moveToStateNow) { //第二個參數默認是false
if (mAdded == null) { mAdded = new ArrayList<Fragment>();}
makeActive(fragment); //添加到mActive集合中
if (!fragment.mDetached) {
if (mAdded.contains(fragment)) {throw new IllegalStateException("Fragment already added: " + fragment); }
mAdded.add(fragment); //添加到mAdded集合中
fragment.mAdded = true;
fragment.mRemoving = false;
if (fragment.mHasMenu && fragment.mMenuVisible) {mNeedMenuInvalidate = true; }
if (moveToStateNow) {moveToState(fragment);} //note1
}
}
void moveToState(int newState, boolean always) {
moveToState(newState, 0, 0, always);
}
void moveToState(int newState, int transit, int transitStyle, boolean always) {
......
mCurState = newState; //note1
if (mActive != null) {
boolean loadersRunning = false;
for (int i=0; i<mActive.size(); i++) {
Fragment f = mActive.get(i); //note2
if (f != null) {
moveToState(f, newState, transit, transitStyle, false);
.......
}
}
......
if (mNeedMenuInvalidate && mHost != null && mCurState == Fragment.RESUMED) {
mHost.onSupportInvalidateOptionsMenu();
mNeedMenuInvalidate = false;
}
}
}
void moveToState(Fragment f) {
moveToState(f, mCurState, 0, 0, false);
}
void moveToState(Fragment f, int newState, int transit, int transitionStyle, boolean keepActive) {
//參數值如:mManager.mCurState,0, 0, true
if ((!f.mAdded || f.mDetached) && newState > Fragment.CREATED) { newState = Fragment.CREATED; }
if (f.mRemoving && newState > f.mState) { newState = f.mState; }
if (f.mDeferStart && f.mState < Fragment.STARTED && newState > Fragment.STOPPED) { newState = Fragment.STOPPED; }
if (f.mState < newState) {
......
switch (f.mState) {
case Fragment.INITIALIZING:
.......
f.mHost = mHost;
f.mParentFragment = mParent;
f.mFragmentManager = mParent != null ? mParent.mChildFragmentManager : mHost.getFragmentManagerImpl();
f.mCalled = false;
f.onAttach(mHost.getContext());//note-1
if (!f.mCalled) { throw new SuperNotCalledException("Fragment " + f + " did not call through to super.onAttach()"); }
if (f.mParentFragment == null) { mHost.onAttachFragment(f); }
if (!f.mRetaining) { f.performCreate(f.mSavedFragmentState); } //note0
f.mRetaining = false;
if (f.mFromLayout) { //Fragment來自於佈局文件
f.mView = f.performCreateView(f.getLayoutInflater( f.mSavedFragmentState), null, f.mSavedFragmentState); //note1
if (f.mView != null) {
f.mInnerView = f.mView;
if (Build.VERSION.SDK_INT >= 11) { ViewCompat.setSaveFromParentEnabled(f.mView, false); }
else { f.mView = NoSaveStateFrameLayout.wrap(f.mView); }
if (f.mHidden) f.mView.setVisibility(View.GONE);
f.onViewCreated(f.mView, f.mSavedFragmentState); //note2
}
else { f.mInnerView = null; }
} //注意這裏沒有break!因此往下繼續執行
case Fragment.CREATED:
if (newState > Fragment.CREATED) {
if (!f.mFromLayout) {
ViewGroup container = null;
if (f.mContainerId != 0) {
container = (ViewGroup)mContainer.onFindViewById(f.mContainerId); //note3
if (container == null && !f.mRestored) { throwException(new IllegalArgumentException( "No view found for id 0x....."); }
}
f.mContainer = container;
f.mView = f.performCreateView(f.getLayoutInflater( f.mSavedFragmentState), container, f.mSavedFragmentState);//note4
if (f.mView != null) {
f.mInnerView = f.mView;
if (Build.VERSION.SDK_INT >= 11) {ViewCompat.setSaveFromParentEnabled(f.mView, false);}
else {f.mView = NoSaveStateFrameLayout.wrap(f.mView); }
if (container != null) {
Animation anim = loadAnimation(f, transit, true,transitionStyle);//note5
if (anim != null) {
setHWLayerAnimListenerIfAlpha(f.mView, anim);
f.mView.startAnimation(anim);
}
container.addView(f.mView);//note6
}
if (f.mHidden) f.mView.setVisibility(View.GONE);
f.onViewCreated(f.mView, f.mSavedFragmentState);//note6.5
}
else { f.mInnerView = null;}
}
f.performActivityCreated(f.mSavedFragmentState);//note7
if (f.mView != null) {f.restoreViewState(f.mSavedFragmentState);}
f.mSavedFragmentState = null;
} //注意這裏沒有break!因此往下繼續執行
case Fragment.ACTIVITY_CREATED:
case Fragment.STOPPED:
if (newState > Fragment.STOPPED) { f.performStart();} //note8
case Fragment.STARTED:
if (newState > Fragment.STARTED) {
f.mResumed = true;
f.performResume(); //note9
f.mSavedFragmentState = null;
f.mSavedViewState = null;
}
}//end of swith
} else if (f.mState > newState) {
switch (f.mState) {
case Fragment.RESUMED:
if (newState < Fragment.RESUMED) {
f.performPause(); //note10
f.mResumed = false;
}
case Fragment.STARTED:
if (newState < Fragment.STARTED) { f.performStop();} //note11
case Fragment.STOPPED:
if (newState < Fragment.STOPPED) {f.performReallyStop();} //note12
case Fragment.ACTIVITY_CREATED:
if (newState < Fragment.ACTIVITY_CREATED) {
if (f.mView != null) {
if (mHost.onShouldSaveFragmentState(f) && f.mSavedViewState == null) { saveFragmentViewState(f);}
}
f.performDestroyView(); //note13
if (f.mView != null && f.mContainer != null) {
Animation anim = null;
if (mCurState > Fragment.INITIALIZING && !mDestroyed) {
anim = loadAnimation(f, transit, false,transitionStyle);
}
if (anim != null) {
final Fragment fragment = f;
f.mAnimatingAway = f.mView;
f.mStateAfterAnimating = newState;
final View viewToAnimate = f.mView;
anim.setAnimationListener(new AnimateOnHWLayerIfNeededListener(viewToAnimate, anim) {
@Override
public void onAnimationEnd(Animation animation) {
super.onAnimationEnd(animation);
if (fragment.mAnimatingAway != null) {
fragment.mAnimatingAway = null;
moveToState(fragment, fragment.mStateAfterAnimating, 0, 0, false);
}
}
});
f.mView.startAnimation(anim);
}
f.mContainer.removeView(f.mView); //note14
}
f.mContainer = null;
f.mView = null;
f.mInnerView = null;
}
case Fragment.CREATED:
if (newState < Fragment.CREATED) {
if (mDestroyed) {
if (f.mAnimatingAway != null) {
View v = f.mAnimatingAway;
f.mAnimatingAway = null;
v.clearAnimation();
}
}
if (f.mAnimatingAway != null) {
f.mStateAfterAnimating = newState;
newState = Fragment.CREATED;
}
else {
if (!f.mRetaining) { f.performDestroy();} //note15
f.mCalled = false;
f.onDetach(); //note16
if (!f.mCalled) { throw new SuperNotCalledException("Fragment " + f+ " did not call through to super.onDetach()"); }
if (!keepActive) {
if (!f.mRetaining) {makeInactive(f); }
else {
f.mHost = null;
f.mParentFragment = null;
f.mFragmentManager = null;
f.mChildFragmentManager = null;
}
}end of if (!keepActive)
}//end of else
}//end of if (newState < Fragment.CREATED)
}//end of switch
}//end of else if (f.mState > newState)
f.mState = newState; //17
}//end of function