+++ /dev/null
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v2.app;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-
-final class BackStackState implements Parcelable {
- final int[] mOps;
- final int mTransition;
- final int mTransitionStyle;
- final String mName;
- final int mIndex;
- final int mBreadCrumbTitleRes;
- final CharSequence mBreadCrumbTitleText;
- final int mBreadCrumbShortTitleRes;
- final CharSequence mBreadCrumbShortTitleText;
-
- public BackStackState(FragmentManagerImpl fm, BackStackRecord bse) {
- int numRemoved = 0;
- BackStackRecord.Op op = bse.mHead;
- while (op != null) {
- if (op.removed != null) numRemoved += op.removed.size();
- op = op.next;
- }
- mOps = new int[bse.mNumOp*5 + numRemoved];
-
- if (!bse.mAddToBackStack) {
- throw new IllegalStateException("Not on back stack");
- }
-
- op = bse.mHead;
- int pos = 0;
- while (op != null) {
- mOps[pos++] = op.cmd;
- mOps[pos++] = op.fragment.mIndex;
- mOps[pos++] = op.enterAnim;
- mOps[pos++] = op.exitAnim;
- if (op.removed != null) {
- final int N = op.removed.size();
- mOps[pos++] = N;
- for (int i=0; i<N; i++) {
- mOps[pos++] = op.removed.get(i).mIndex;
- }
- } else {
- mOps[pos++] = 0;
- }
- op = op.next;
- }
- mTransition = bse.mTransition;
- mTransitionStyle = bse.mTransitionStyle;
- mName = bse.mName;
- mIndex = bse.mIndex;
- mBreadCrumbTitleRes = bse.mBreadCrumbTitleRes;
- mBreadCrumbTitleText = bse.mBreadCrumbTitleText;
- mBreadCrumbShortTitleRes = bse.mBreadCrumbShortTitleRes;
- mBreadCrumbShortTitleText = bse.mBreadCrumbShortTitleText;
- }
-
- public BackStackState(Parcel in) {
- mOps = in.createIntArray();
- mTransition = in.readInt();
- mTransitionStyle = in.readInt();
- mName = in.readString();
- mIndex = in.readInt();
- mBreadCrumbTitleRes = in.readInt();
- mBreadCrumbTitleText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
- mBreadCrumbShortTitleRes = in.readInt();
- mBreadCrumbShortTitleText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
- }
-
- public BackStackRecord instantiate(FragmentManagerImpl fm) {
- BackStackRecord bse = new BackStackRecord(fm);
- int pos = 0;
- while (pos < mOps.length) {
- BackStackRecord.Op op = new BackStackRecord.Op();
- op.cmd = mOps[pos++];
- if (FragmentManagerImpl.DEBUG) Log.v(FragmentManagerImpl.TAG,
- "BSE " + bse + " set base fragment #" + mOps[pos]);
- Fragment f = fm.mActive.get(mOps[pos++]);
- op.fragment = f;
- op.enterAnim = mOps[pos++];
- op.exitAnim = mOps[pos++];
- final int N = mOps[pos++];
- if (N > 0) {
- op.removed = new ArrayList<Fragment>(N);
- for (int i=0; i<N; i++) {
- if (FragmentManagerImpl.DEBUG) Log.v(FragmentManagerImpl.TAG,
- "BSE " + bse + " set remove fragment #" + mOps[pos]);
- Fragment r = fm.mActive.get(mOps[pos++]);
- op.removed.add(r);
- }
- }
- bse.addOp(op);
- }
- bse.mTransition = mTransition;
- bse.mTransitionStyle = mTransitionStyle;
- bse.mName = mName;
- bse.mIndex = mIndex;
- bse.mAddToBackStack = true;
- bse.mBreadCrumbTitleRes = mBreadCrumbTitleRes;
- bse.mBreadCrumbTitleText = mBreadCrumbTitleText;
- bse.mBreadCrumbShortTitleRes = mBreadCrumbShortTitleRes;
- bse.mBreadCrumbShortTitleText = mBreadCrumbShortTitleText;
- bse.bumpBackStackNesting(1);
- return bse;
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeIntArray(mOps);
- dest.writeInt(mTransition);
- dest.writeInt(mTransitionStyle);
- dest.writeString(mName);
- dest.writeInt(mIndex);
- dest.writeInt(mBreadCrumbTitleRes);
- TextUtils.writeToParcel(mBreadCrumbTitleText, dest, 0);
- dest.writeInt(mBreadCrumbShortTitleRes);
- TextUtils.writeToParcel(mBreadCrumbShortTitleText, dest, 0);
- }
-
- public static final Parcelable.Creator<BackStackState> CREATOR
- = new Parcelable.Creator<BackStackState>() {
- public BackStackState createFromParcel(Parcel in) {
- return new BackStackState(in);
- }
-
- public BackStackState[] newArray(int size) {
- return new BackStackState[size];
- }
- };
-}
-
-/**
- * @hide Entry of an operation on the fragment back stack.
- */
-final class BackStackRecord extends FragmentTransaction implements
- FragmentManager.BackStackEntry, Runnable {
- static final String TAG = "BackStackEntry";
-
- final FragmentManagerImpl mManager;
-
- static final int OP_NULL = 0;
- static final int OP_ADD = 1;
- static final int OP_REPLACE = 2;
- static final int OP_REMOVE = 3;
- static final int OP_HIDE = 4;
- static final int OP_SHOW = 5;
-
- static final class Op {
- Op next;
- Op prev;
- int cmd;
- Fragment fragment;
- int enterAnim;
- int exitAnim;
- ArrayList<Fragment> removed;
- }
-
- Op mHead;
- Op mTail;
- int mNumOp;
- int mEnterAnim;
- int mExitAnim;
- int mTransition;
- int mTransitionStyle;
- boolean mAddToBackStack;
- boolean mAllowAddToBackStack = true;
- String mName;
- boolean mCommitted;
- int mIndex;
-
- int mBreadCrumbTitleRes;
- CharSequence mBreadCrumbTitleText;
- int mBreadCrumbShortTitleRes;
- CharSequence mBreadCrumbShortTitleText;
-
- public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
- writer.print(prefix); writer.print("mName="); writer.print(mName);
- writer.print(" mIndex="); writer.print(mIndex);
- writer.print(" mCommitted="); writer.println(mCommitted);
- if (mTransition != FragmentTransaction.TRANSIT_NONE) {
- writer.print(prefix); writer.print("mTransition=#");
- writer.print(Integer.toHexString(mTransition));
- writer.print(" mTransitionStyle=#");
- writer.println(Integer.toHexString(mTransitionStyle));
- }
- if (mEnterAnim != 0 || mExitAnim !=0) {
- writer.print(prefix); writer.print("mEnterAnim=#");
- writer.print(Integer.toHexString(mEnterAnim));
- writer.print(" mExitAnim=#");
- writer.println(Integer.toHexString(mExitAnim));
- }
- if (mBreadCrumbTitleRes != 0 || mBreadCrumbTitleText != null) {
- writer.print(prefix); writer.print("mBreadCrumbTitleRes=#");
- writer.print(Integer.toHexString(mBreadCrumbTitleRes));
- writer.print(" mBreadCrumbTitleText=");
- writer.println(mBreadCrumbTitleText);
- }
- if (mBreadCrumbShortTitleRes != 0 || mBreadCrumbShortTitleText != null) {
- writer.print(prefix); writer.print("mBreadCrumbShortTitleRes=#");
- writer.print(Integer.toHexString(mBreadCrumbShortTitleRes));
- writer.print(" mBreadCrumbShortTitleText=");
- writer.println(mBreadCrumbShortTitleText);
- }
-
- if (mHead != null) {
- writer.print(prefix); writer.println("Operations:");
- String innerPrefix = prefix + " ";
- Op op = mHead;
- int num = 0;
- while (op != null) {
- writer.print(prefix); writer.print(" Op #"); writer.print(num);
- writer.println(":");
- writer.print(innerPrefix); writer.print("cmd="); writer.print(op.cmd);
- writer.print(" fragment="); writer.println(op.fragment);
- if (op.enterAnim != 0 || op.exitAnim != 0) {
- writer.print(prefix); writer.print("enterAnim="); writer.print(op.enterAnim);
- writer.print(" exitAnim="); writer.println(op.exitAnim);
- }
- if (op.removed != null && op.removed.size() > 0) {
- for (int i=0; i<op.removed.size(); i++) {
- writer.print(innerPrefix);
- if (op.removed.size() == 1) {
- writer.print("Removed: ");
- } else {
- writer.println("Removed:");
- writer.print(innerPrefix); writer.print(" #"); writer.print(num);
- writer.print(": ");
- }
- writer.println(op.removed.get(i));
- }
- }
- op = op.next;
- }
- }
- }
-
- public BackStackRecord(FragmentManagerImpl manager) {
- mManager = manager;
- }
-
- public int getId() {
- return mIndex;
- }
-
- public int getBreadCrumbTitleRes() {
- return mBreadCrumbTitleRes;
- }
-
- public int getBreadCrumbShortTitleRes() {
- return mBreadCrumbShortTitleRes;
- }
-
- public CharSequence getBreadCrumbTitle() {
- if (mBreadCrumbTitleRes != 0) {
- return mManager.mActivity.getText(mBreadCrumbTitleRes);
- }
- return mBreadCrumbTitleText;
- }
-
- public CharSequence getBreadCrumbShortTitle() {
- if (mBreadCrumbShortTitleRes != 0) {
- return mManager.mActivity.getText(mBreadCrumbShortTitleRes);
- }
- return mBreadCrumbShortTitleText;
- }
-
- void addOp(Op op) {
- if (mHead == null) {
- mHead = mTail = op;
- } else {
- op.prev = mTail;
- mTail.next = op;
- mTail = op;
- }
- op.enterAnim = mEnterAnim;
- op.exitAnim = mExitAnim;
- mNumOp++;
- }
-
- public FragmentTransaction add(Fragment fragment, String tag) {
- doAddOp(0, fragment, tag, OP_ADD);
- return this;
- }
-
- public FragmentTransaction add(int containerViewId, Fragment fragment) {
- doAddOp(containerViewId, fragment, null, OP_ADD);
- return this;
- }
-
- public FragmentTransaction add(int containerViewId, Fragment fragment, String tag) {
- doAddOp(containerViewId, fragment, tag, OP_ADD);
- return this;
- }
-
- private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) {
- if (fragment.mImmediateActivity != null) {
- throw new IllegalStateException("Fragment already added: " + fragment);
- }
- fragment.mImmediateActivity = mManager.mActivity;
- 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;
- }
-
- Op op = new Op();
- op.cmd = opcmd;
- op.fragment = fragment;
- addOp(op);
- }
-
- public FragmentTransaction replace(int containerViewId, Fragment fragment) {
- return replace(containerViewId, fragment, null);
- }
-
- public FragmentTransaction replace(int containerViewId, Fragment fragment, String tag) {
- if (containerViewId == 0) {
- throw new IllegalArgumentException("Must use non-zero containerViewId");
- }
-
- doAddOp(containerViewId, fragment, tag, OP_REPLACE);
- return this;
- }
-
- public FragmentTransaction remove(Fragment fragment) {
- if (fragment.mImmediateActivity == null) {
- throw new IllegalStateException("Fragment not added: " + fragment);
- }
- fragment.mImmediateActivity = null;
-
- Op op = new Op();
- op.cmd = OP_REMOVE;
- op.fragment = fragment;
- addOp(op);
-
- return this;
- }
-
- public FragmentTransaction hide(Fragment fragment) {
- if (fragment.mImmediateActivity == null) {
- throw new IllegalStateException("Fragment not added: " + fragment);
- }
-
- Op op = new Op();
- op.cmd = OP_HIDE;
- op.fragment = fragment;
- addOp(op);
-
- return this;
- }
-
- public FragmentTransaction show(Fragment fragment) {
- if (fragment.mImmediateActivity == null) {
- throw new IllegalStateException("Fragment not added: " + fragment);
- }
-
- Op op = new Op();
- op.cmd = OP_SHOW;
- op.fragment = fragment;
- addOp(op);
-
- return this;
- }
-
- public FragmentTransaction setCustomAnimations(int enter, int exit) {
- mEnterAnim = enter;
- mExitAnim = exit;
- return this;
- }
-
- public FragmentTransaction setTransition(int transition) {
- mTransition = transition;
- return this;
- }
-
- public FragmentTransaction setTransitionStyle(int styleRes) {
- mTransitionStyle = styleRes;
- return this;
- }
-
- public FragmentTransaction addToBackStack(String name) {
- if (!mAllowAddToBackStack) {
- throw new IllegalStateException(
- "This FragmentTransaction is not allowed to be added to the back stack.");
- }
- mAddToBackStack = true;
- mName = name;
- return this;
- }
-
- public boolean isAddToBackStackAllowed() {
- return mAllowAddToBackStack;
- }
-
- public FragmentTransaction disallowAddToBackStack() {
- if (mAddToBackStack) {
- throw new IllegalStateException(
- "This transaction is already being added to the back stack");
- }
- mAllowAddToBackStack = false;
- return this;
- }
-
- public FragmentTransaction setBreadCrumbTitle(int res) {
- mBreadCrumbTitleRes = res;
- mBreadCrumbTitleText = null;
- return this;
- }
-
- public FragmentTransaction setBreadCrumbTitle(CharSequence text) {
- mBreadCrumbTitleRes = 0;
- mBreadCrumbTitleText = text;
- return this;
- }
-
- public FragmentTransaction setBreadCrumbShortTitle(int res) {
- mBreadCrumbShortTitleRes = res;
- mBreadCrumbShortTitleText = null;
- return this;
- }
-
- public FragmentTransaction setBreadCrumbShortTitle(CharSequence text) {
- mBreadCrumbShortTitleRes = 0;
- mBreadCrumbShortTitleText = text;
- return this;
- }
-
- void bumpBackStackNesting(int amt) {
- if (!mAddToBackStack) {
- return;
- }
- if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting in " + this
- + " by " + amt);
- Op op = mHead;
- while (op != null) {
- op.fragment.mBackStackNesting += amt;
- if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting of "
- + op.fragment + " to " + op.fragment.mBackStackNesting);
- if (op.removed != null) {
- for (int i=op.removed.size()-1; i>=0; i--) {
- Fragment r = op.removed.get(i);
- r.mBackStackNesting += amt;
- if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting of "
- + r + " to " + r.mBackStackNesting);
- }
- }
- op = op.next;
- }
- }
-
- public int commit() {
- return commitInternal(false);
- }
-
- public int commitAllowingStateLoss() {
- return commitInternal(true);
- }
-
- int commitInternal(boolean allowStateLoss) {
- if (mCommitted) throw new IllegalStateException("commit already called");
- if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Commit: " + this);
- mCommitted = true;
- if (mAddToBackStack) {
- mIndex = mManager.allocBackStackIndex(this);
- } else {
- mIndex = -1;
- }
- mManager.enqueueAction(this, allowStateLoss);
- return mIndex;
- }
-
- public void run() {
- if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Run: " + this);
-
- if (mAddToBackStack) {
- if (mIndex < 0) {
- throw new IllegalStateException("addToBackStack() called after commit()");
- }
- }
-
- bumpBackStackNesting(1);
-
- Op op = mHead;
- while (op != null) {
- switch (op.cmd) {
- case OP_ADD: {
- Fragment f = op.fragment;
- f.mNextAnim = op.enterAnim;
- mManager.addFragment(f, false);
- } break;
- case OP_REPLACE: {
- Fragment f = op.fragment;
- if (mManager.mAdded != null) {
- for (int i=0; i<mManager.mAdded.size(); i++) {
- Fragment old = mManager.mAdded.get(i);
- if (FragmentManagerImpl.DEBUG) Log.v(TAG,
- "OP_REPLACE: adding=" + f + " old=" + old);
- if (old.mContainerId == f.mContainerId) {
- if (op.removed == null) {
- op.removed = new ArrayList<Fragment>();
- }
- op.removed.add(old);
- old.mNextAnim = op.exitAnim;
- if (mAddToBackStack) {
- old.mBackStackNesting += 1;
- if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting of "
- + old + " to " + old.mBackStackNesting);
- }
- mManager.removeFragment(old, mTransition, mTransitionStyle);
- }
- }
- }
- f.mNextAnim = op.enterAnim;
- mManager.addFragment(f, false);
- } break;
- case OP_REMOVE: {
- Fragment f = op.fragment;
- f.mNextAnim = op.exitAnim;
- mManager.removeFragment(f, mTransition, mTransitionStyle);
- } break;
- case OP_HIDE: {
- Fragment f = op.fragment;
- f.mNextAnim = op.exitAnim;
- mManager.hideFragment(f, mTransition, mTransitionStyle);
- } break;
- case OP_SHOW: {
- Fragment f = op.fragment;
- f.mNextAnim = op.enterAnim;
- mManager.showFragment(f, mTransition, mTransitionStyle);
- } break;
- default: {
- throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
- }
- }
-
- op = op.next;
- }
-
- mManager.moveToState(mManager.mCurState, mTransition,
- mTransitionStyle, true);
-
- if (mAddToBackStack) {
- mManager.addBackStackState(this);
- }
- }
-
- public void popFromBackStack(boolean doStateMove) {
- if (FragmentManagerImpl.DEBUG) Log.v(TAG, "popFromBackStack: " + this);
-
- bumpBackStackNesting(-1);
-
- Op op = mTail;
- while (op != null) {
- switch (op.cmd) {
- case OP_ADD: {
- Fragment f = op.fragment;
- f.mImmediateActivity = null;
- mManager.removeFragment(f,
- FragmentManagerImpl.reverseTransit(mTransition),
- mTransitionStyle);
- } break;
- case OP_REPLACE: {
- Fragment f = op.fragment;
- f.mImmediateActivity = null;
- mManager.removeFragment(f,
- FragmentManagerImpl.reverseTransit(mTransition),
- mTransitionStyle);
- if (op.removed != null) {
- for (int i=0; i<op.removed.size(); i++) {
- Fragment old = op.removed.get(i);
- f.mImmediateActivity = mManager.mActivity;
- mManager.addFragment(old, false);
- }
- }
- } break;
- case OP_REMOVE: {
- Fragment f = op.fragment;
- f.mImmediateActivity = mManager.mActivity;
- mManager.addFragment(f, false);
- } break;
- case OP_HIDE: {
- Fragment f = op.fragment;
- mManager.showFragment(f,
- FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
- } break;
- case OP_SHOW: {
- Fragment f = op.fragment;
- mManager.hideFragment(f,
- FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
- } break;
- default: {
- throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
- }
- }
-
- op = op.prev;
- }
-
- if (doStateMove) {
- mManager.moveToState(mManager.mCurState,
- FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle, true);
- }
-
- if (mIndex >= 0) {
- mManager.freeBackStackIndex(mIndex);
- mIndex = -1;
- }
- }
-
- public String getName() {
- return mName;
- }
-
- public int getTransition() {
- return mTransition;
- }
-
- public int getTransitionStyle() {
- return mTransitionStyle;
- }
-
- public boolean isEmpty() {
- return mNumOp == 0;
- }
-}