blob: e5a7980b0c8c98103ebe6792ea88af3857a8396f [file] [log] [blame]
Dianne Hackborn5ae74d62010-05-19 19:14:57 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
19import android.os.Parcel;
20import android.os.Parcelable;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070021import android.text.TextUtils;
Dianne Hackborn445646c2010-06-25 15:52:59 -070022import android.util.Log;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070023
Dianne Hackborn30d71892010-12-11 10:37:55 -080024import java.io.FileDescriptor;
25import java.io.PrintWriter;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070026import java.util.ArrayList;
27
28final class BackStackState implements Parcelable {
29 final int[] mOps;
30 final int mTransition;
31 final int mTransitionStyle;
32 final String mName;
Dianne Hackborndd913a52010-07-22 12:17:04 -070033 final int mIndex;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070034 final int mBreadCrumbTitleRes;
35 final CharSequence mBreadCrumbTitleText;
36 final int mBreadCrumbShortTitleRes;
37 final CharSequence mBreadCrumbShortTitleText;
38
39 public BackStackState(FragmentManagerImpl fm, BackStackRecord bse) {
Dianne Hackborn445646c2010-06-25 15:52:59 -070040 int numRemoved = 0;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070041 BackStackRecord.Op op = bse.mHead;
Dianne Hackborn445646c2010-06-25 15:52:59 -070042 while (op != null) {
43 if (op.removed != null) numRemoved += op.removed.size();
44 op = op.next;
45 }
Chet Haasebc377842011-03-22 11:35:22 -070046 mOps = new int[bse.mNumOp*7 + numRemoved];
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070047
Dianne Hackbornb7a2e472010-08-12 16:20:42 -070048 if (!bse.mAddToBackStack) {
49 throw new IllegalStateException("Not on back stack");
50 }
51
Dianne Hackborn445646c2010-06-25 15:52:59 -070052 op = bse.mHead;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070053 int pos = 0;
54 while (op != null) {
55 mOps[pos++] = op.cmd;
56 mOps[pos++] = op.fragment.mIndex;
57 mOps[pos++] = op.enterAnim;
58 mOps[pos++] = op.exitAnim;
Chet Haasebc377842011-03-22 11:35:22 -070059 mOps[pos++] = op.popEnterAnim;
60 mOps[pos++] = op.popExitAnim;
Dianne Hackborn445646c2010-06-25 15:52:59 -070061 if (op.removed != null) {
62 final int N = op.removed.size();
63 mOps[pos++] = N;
64 for (int i=0; i<N; i++) {
65 mOps[pos++] = op.removed.get(i).mIndex;
66 }
67 } else {
68 mOps[pos++] = 0;
69 }
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070070 op = op.next;
71 }
72 mTransition = bse.mTransition;
73 mTransitionStyle = bse.mTransitionStyle;
74 mName = bse.mName;
Dianne Hackborndd913a52010-07-22 12:17:04 -070075 mIndex = bse.mIndex;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070076 mBreadCrumbTitleRes = bse.mBreadCrumbTitleRes;
77 mBreadCrumbTitleText = bse.mBreadCrumbTitleText;
78 mBreadCrumbShortTitleRes = bse.mBreadCrumbShortTitleRes;
79 mBreadCrumbShortTitleText = bse.mBreadCrumbShortTitleText;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070080 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070081
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070082 public BackStackState(Parcel in) {
83 mOps = in.createIntArray();
84 mTransition = in.readInt();
85 mTransitionStyle = in.readInt();
86 mName = in.readString();
Dianne Hackborndd913a52010-07-22 12:17:04 -070087 mIndex = in.readInt();
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070088 mBreadCrumbTitleRes = in.readInt();
89 mBreadCrumbTitleText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
90 mBreadCrumbShortTitleRes = in.readInt();
91 mBreadCrumbShortTitleText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070092 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070093
94 public BackStackRecord instantiate(FragmentManagerImpl fm) {
95 BackStackRecord bse = new BackStackRecord(fm);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070096 int pos = 0;
97 while (pos < mOps.length) {
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070098 BackStackRecord.Op op = new BackStackRecord.Op();
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070099 op.cmd = mOps[pos++];
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700100 if (FragmentManagerImpl.DEBUG) Log.v(FragmentManagerImpl.TAG,
101 "BSE " + bse + " set base fragment #" + mOps[pos]);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700102 Fragment f = fm.mActive.get(mOps[pos++]);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700103 op.fragment = f;
104 op.enterAnim = mOps[pos++];
105 op.exitAnim = mOps[pos++];
Chet Haasebc377842011-03-22 11:35:22 -0700106 op.popEnterAnim = mOps[pos++];
107 op.popExitAnim = mOps[pos++];
Dianne Hackborn445646c2010-06-25 15:52:59 -0700108 final int N = mOps[pos++];
109 if (N > 0) {
110 op.removed = new ArrayList<Fragment>(N);
111 for (int i=0; i<N; i++) {
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700112 if (FragmentManagerImpl.DEBUG) Log.v(FragmentManagerImpl.TAG,
113 "BSE " + bse + " set remove fragment #" + mOps[pos]);
114 Fragment r = fm.mActive.get(mOps[pos++]);
115 op.removed.add(r);
Dianne Hackborn445646c2010-06-25 15:52:59 -0700116 }
117 }
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700118 bse.addOp(op);
119 }
120 bse.mTransition = mTransition;
121 bse.mTransitionStyle = mTransitionStyle;
122 bse.mName = mName;
Dianne Hackborndd913a52010-07-22 12:17:04 -0700123 bse.mIndex = mIndex;
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700124 bse.mAddToBackStack = true;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700125 bse.mBreadCrumbTitleRes = mBreadCrumbTitleRes;
126 bse.mBreadCrumbTitleText = mBreadCrumbTitleText;
127 bse.mBreadCrumbShortTitleRes = mBreadCrumbShortTitleRes;
128 bse.mBreadCrumbShortTitleText = mBreadCrumbShortTitleText;
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700129 bse.bumpBackStackNesting(1);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700130 return bse;
131 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700132
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700133 public int describeContents() {
134 return 0;
135 }
136
137 public void writeToParcel(Parcel dest, int flags) {
138 dest.writeIntArray(mOps);
139 dest.writeInt(mTransition);
140 dest.writeInt(mTransitionStyle);
141 dest.writeString(mName);
Dianne Hackborndd913a52010-07-22 12:17:04 -0700142 dest.writeInt(mIndex);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700143 dest.writeInt(mBreadCrumbTitleRes);
144 TextUtils.writeToParcel(mBreadCrumbTitleText, dest, 0);
145 dest.writeInt(mBreadCrumbShortTitleRes);
146 TextUtils.writeToParcel(mBreadCrumbShortTitleText, dest, 0);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700147 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700148
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700149 public static final Parcelable.Creator<BackStackState> CREATOR
150 = new Parcelable.Creator<BackStackState>() {
151 public BackStackState createFromParcel(Parcel in) {
152 return new BackStackState(in);
153 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700154
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700155 public BackStackState[] newArray(int size) {
156 return new BackStackState[size];
157 }
158 };
159}
160
161/**
162 * @hide Entry of an operation on the fragment back stack.
163 */
Dianne Hackbornab36acb2010-11-05 14:12:11 -0700164final class BackStackRecord extends FragmentTransaction implements
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700165 FragmentManager.BackStackEntry, Runnable {
Dianne Hackborn445646c2010-06-25 15:52:59 -0700166 static final String TAG = "BackStackEntry";
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700167
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700168 final FragmentManagerImpl mManager;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700169
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700170 static final int OP_NULL = 0;
171 static final int OP_ADD = 1;
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700172 static final int OP_REPLACE = 2;
173 static final int OP_REMOVE = 3;
174 static final int OP_HIDE = 4;
175 static final int OP_SHOW = 5;
Dianne Hackborn47c41562011-04-15 19:00:20 -0700176 static final int OP_DETACH = 6;
177 static final int OP_ATTACH = 7;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700178
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700179 static final class Op {
180 Op next;
181 Op prev;
182 int cmd;
183 Fragment fragment;
184 int enterAnim;
185 int exitAnim;
Chet Haasebc377842011-03-22 11:35:22 -0700186 int popEnterAnim;
187 int popExitAnim;
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700188 ArrayList<Fragment> removed;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700189 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700190
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700191 Op mHead;
192 Op mTail;
193 int mNumOp;
194 int mEnterAnim;
195 int mExitAnim;
Chet Haasebc377842011-03-22 11:35:22 -0700196 int mPopEnterAnim;
197 int mPopExitAnim;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700198 int mTransition;
199 int mTransitionStyle;
200 boolean mAddToBackStack;
Adam Powell0c24a552010-11-03 16:44:11 -0700201 boolean mAllowAddToBackStack = true;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700202 String mName;
203 boolean mCommitted;
Dianne Hackborndd913a52010-07-22 12:17:04 -0700204 int mIndex;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700205
206 int mBreadCrumbTitleRes;
207 CharSequence mBreadCrumbTitleText;
208 int mBreadCrumbShortTitleRes;
209 CharSequence mBreadCrumbShortTitleText;
210
Dianne Hackborn30d71892010-12-11 10:37:55 -0800211 public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
212 writer.print(prefix); writer.print("mName="); writer.print(mName);
213 writer.print(" mIndex="); writer.print(mIndex);
214 writer.print(" mCommitted="); writer.println(mCommitted);
215 if (mTransition != FragmentTransaction.TRANSIT_NONE) {
216 writer.print(prefix); writer.print("mTransition=#");
217 writer.print(Integer.toHexString(mTransition));
218 writer.print(" mTransitionStyle=#");
219 writer.println(Integer.toHexString(mTransitionStyle));
220 }
221 if (mEnterAnim != 0 || mExitAnim !=0) {
222 writer.print(prefix); writer.print("mEnterAnim=#");
223 writer.print(Integer.toHexString(mEnterAnim));
224 writer.print(" mExitAnim=#");
225 writer.println(Integer.toHexString(mExitAnim));
226 }
227 if (mBreadCrumbTitleRes != 0 || mBreadCrumbTitleText != null) {
228 writer.print(prefix); writer.print("mBreadCrumbTitleRes=#");
229 writer.print(Integer.toHexString(mBreadCrumbTitleRes));
230 writer.print(" mBreadCrumbTitleText=");
231 writer.println(mBreadCrumbTitleText);
232 }
233 if (mBreadCrumbShortTitleRes != 0 || mBreadCrumbShortTitleText != null) {
234 writer.print(prefix); writer.print("mBreadCrumbShortTitleRes=#");
235 writer.print(Integer.toHexString(mBreadCrumbShortTitleRes));
236 writer.print(" mBreadCrumbShortTitleText=");
237 writer.println(mBreadCrumbShortTitleText);
238 }
239
240 if (mHead != null) {
241 writer.print(prefix); writer.println("Operations:");
242 String innerPrefix = prefix + " ";
243 Op op = mHead;
244 int num = 0;
245 while (op != null) {
Dianne Hackbornd2835932010-12-13 16:28:46 -0800246 writer.print(prefix); writer.print(" Op #"); writer.print(num);
247 writer.println(":");
Dianne Hackborn30d71892010-12-11 10:37:55 -0800248 writer.print(innerPrefix); writer.print("cmd="); writer.print(op.cmd);
Dianne Hackbornd2835932010-12-13 16:28:46 -0800249 writer.print(" fragment="); writer.println(op.fragment);
Dianne Hackborn30d71892010-12-11 10:37:55 -0800250 if (op.enterAnim != 0 || op.exitAnim != 0) {
251 writer.print(prefix); writer.print("enterAnim="); writer.print(op.enterAnim);
252 writer.print(" exitAnim="); writer.println(op.exitAnim);
253 }
Chet Haasebc377842011-03-22 11:35:22 -0700254 if (op.popEnterAnim != 0 || op.popExitAnim != 0) {
255 writer.print(prefix);
256 writer.print("popEnterAnim="); writer.print(op.popEnterAnim);
257 writer.print(" popExitAnim="); writer.println(op.popExitAnim);
258 }
Dianne Hackborn30d71892010-12-11 10:37:55 -0800259 if (op.removed != null && op.removed.size() > 0) {
260 for (int i=0; i<op.removed.size(); i++) {
Dianne Hackbornd2835932010-12-13 16:28:46 -0800261 writer.print(innerPrefix);
262 if (op.removed.size() == 1) {
263 writer.print("Removed: ");
264 } else {
265 writer.println("Removed:");
266 writer.print(innerPrefix); writer.print(" #"); writer.print(num);
267 writer.print(": ");
268 }
269 writer.println(op.removed.get(i));
Dianne Hackborn30d71892010-12-11 10:37:55 -0800270 }
271 }
272 op = op.next;
273 }
274 }
275 }
276
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700277 public BackStackRecord(FragmentManagerImpl manager) {
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700278 mManager = manager;
279 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700280
281 public int getId() {
282 return mIndex;
283 }
284
Dianne Hackborn327fbd22011-01-17 14:38:50 -0800285 public int getBreadCrumbTitleRes() {
286 return mBreadCrumbTitleRes;
287 }
288
289 public int getBreadCrumbShortTitleRes() {
290 return mBreadCrumbShortTitleRes;
291 }
292
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700293 public CharSequence getBreadCrumbTitle() {
294 if (mBreadCrumbTitleRes != 0) {
295 return mManager.mActivity.getText(mBreadCrumbTitleRes);
296 }
297 return mBreadCrumbTitleText;
298 }
299
300 public CharSequence getBreadCrumbShortTitle() {
301 if (mBreadCrumbShortTitleRes != 0) {
302 return mManager.mActivity.getText(mBreadCrumbShortTitleRes);
303 }
304 return mBreadCrumbShortTitleText;
305 }
306
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700307 void addOp(Op op) {
308 if (mHead == null) {
309 mHead = mTail = op;
310 } else {
311 op.prev = mTail;
312 mTail.next = op;
313 mTail = op;
314 }
315 op.enterAnim = mEnterAnim;
316 op.exitAnim = mExitAnim;
Chet Haasebc377842011-03-22 11:35:22 -0700317 op.popEnterAnim = mPopEnterAnim;
318 op.popExitAnim = mPopExitAnim;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700319 mNumOp++;
320 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700321
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700322 public FragmentTransaction add(Fragment fragment, String tag) {
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700323 doAddOp(0, fragment, tag, OP_ADD);
324 return this;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700325 }
326
327 public FragmentTransaction add(int containerViewId, Fragment fragment) {
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700328 doAddOp(containerViewId, fragment, null, OP_ADD);
329 return this;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700330 }
331
332 public FragmentTransaction add(int containerViewId, Fragment fragment, String tag) {
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700333 doAddOp(containerViewId, fragment, tag, OP_ADD);
334 return this;
335 }
336
337 private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) {
338 if (fragment.mImmediateActivity != null) {
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700339 throw new IllegalStateException("Fragment already added: " + fragment);
340 }
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700341 fragment.mImmediateActivity = mManager.mActivity;
Dianne Hackborn3e449ce2010-09-11 20:52:31 -0700342 fragment.mFragmentManager = mManager;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700343
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700344 if (tag != null) {
345 if (fragment.mTag != null && !tag.equals(fragment.mTag)) {
346 throw new IllegalStateException("Can't change tag of fragment "
347 + fragment + ": was " + fragment.mTag
348 + " now " + tag);
349 }
350 fragment.mTag = tag;
351 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700352
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700353 if (containerViewId != 0) {
354 if (fragment.mFragmentId != 0 && fragment.mFragmentId != containerViewId) {
355 throw new IllegalStateException("Can't change container ID of fragment "
356 + fragment + ": was " + fragment.mFragmentId
357 + " now " + containerViewId);
358 }
359 fragment.mContainerId = fragment.mFragmentId = containerViewId;
360 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700361
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700362 Op op = new Op();
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700363 op.cmd = opcmd;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700364 op.fragment = fragment;
365 addOp(op);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700366 }
367
368 public FragmentTransaction replace(int containerViewId, Fragment fragment) {
369 return replace(containerViewId, fragment, null);
370 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700371
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700372 public FragmentTransaction replace(int containerViewId, Fragment fragment, String tag) {
373 if (containerViewId == 0) {
374 throw new IllegalArgumentException("Must use non-zero containerViewId");
375 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700376
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700377 doAddOp(containerViewId, fragment, tag, OP_REPLACE);
378 return this;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700379 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700380
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700381 public FragmentTransaction remove(Fragment fragment) {
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700382 if (fragment.mImmediateActivity == null) {
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700383 throw new IllegalStateException("Fragment not added: " + fragment);
384 }
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700385 fragment.mImmediateActivity = null;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700386
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700387 Op op = new Op();
388 op.cmd = OP_REMOVE;
389 op.fragment = fragment;
390 addOp(op);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700391
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700392 return this;
393 }
394
395 public FragmentTransaction hide(Fragment fragment) {
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700396 if (fragment.mImmediateActivity == null) {
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700397 throw new IllegalStateException("Fragment not added: " + fragment);
398 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700399
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700400 Op op = new Op();
401 op.cmd = OP_HIDE;
402 op.fragment = fragment;
403 addOp(op);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700404
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700405 return this;
406 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700407
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700408 public FragmentTransaction show(Fragment fragment) {
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700409 if (fragment.mImmediateActivity == null) {
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700410 throw new IllegalStateException("Fragment not added: " + fragment);
411 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700412
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700413 Op op = new Op();
414 op.cmd = OP_SHOW;
415 op.fragment = fragment;
416 addOp(op);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700417
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700418 return this;
419 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700420
Dianne Hackborn47c41562011-04-15 19:00:20 -0700421 public FragmentTransaction detach(Fragment fragment) {
422 //if (fragment.mImmediateActivity == null) {
423 // throw new IllegalStateException("Fragment not added: " + fragment);
424 //}
425
426 Op op = new Op();
427 op.cmd = OP_DETACH;
428 op.fragment = fragment;
429 addOp(op);
430
431 return this;
432 }
433
434 public FragmentTransaction attach(Fragment fragment) {
435 //if (fragment.mImmediateActivity == null) {
436 // throw new IllegalStateException("Fragment not added: " + fragment);
437 //}
438
439 Op op = new Op();
440 op.cmd = OP_ATTACH;
441 op.fragment = fragment;
442 addOp(op);
443
444 return this;
445 }
446
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700447 public FragmentTransaction setCustomAnimations(int enter, int exit) {
Chet Haasebc377842011-03-22 11:35:22 -0700448 return setCustomAnimations(enter, exit, 0, 0);
449 }
450
451 public FragmentTransaction setCustomAnimations(int enter, int exit,
452 int popEnter, int popExit) {
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700453 mEnterAnim = enter;
454 mExitAnim = exit;
Chet Haasebc377842011-03-22 11:35:22 -0700455 mPopEnterAnim = popEnter;
456 mPopExitAnim = popExit;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700457 return this;
458 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700459
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700460 public FragmentTransaction setTransition(int transition) {
461 mTransition = transition;
462 return this;
463 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700464
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700465 public FragmentTransaction setTransitionStyle(int styleRes) {
466 mTransitionStyle = styleRes;
467 return this;
468 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700469
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700470 public FragmentTransaction addToBackStack(String name) {
Adam Powell0c24a552010-11-03 16:44:11 -0700471 if (!mAllowAddToBackStack) {
472 throw new IllegalStateException(
473 "This FragmentTransaction is not allowed to be added to the back stack.");
474 }
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700475 mAddToBackStack = true;
476 mName = name;
477 return this;
478 }
479
Adam Powell0c24a552010-11-03 16:44:11 -0700480 public boolean isAddToBackStackAllowed() {
481 return mAllowAddToBackStack;
482 }
483
484 public FragmentTransaction disallowAddToBackStack() {
485 if (mAddToBackStack) {
486 throw new IllegalStateException(
487 "This transaction is already being added to the back stack");
488 }
489 mAllowAddToBackStack = false;
490 return this;
491 }
492
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700493 public FragmentTransaction setBreadCrumbTitle(int res) {
494 mBreadCrumbTitleRes = res;
495 mBreadCrumbTitleText = null;
496 return this;
497 }
498
499 public FragmentTransaction setBreadCrumbTitle(CharSequence text) {
500 mBreadCrumbTitleRes = 0;
501 mBreadCrumbTitleText = text;
502 return this;
503 }
504
505 public FragmentTransaction setBreadCrumbShortTitle(int res) {
506 mBreadCrumbShortTitleRes = res;
507 mBreadCrumbShortTitleText = null;
508 return this;
509 }
510
511 public FragmentTransaction setBreadCrumbShortTitle(CharSequence text) {
512 mBreadCrumbShortTitleRes = 0;
513 mBreadCrumbShortTitleText = text;
514 return this;
515 }
516
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700517 void bumpBackStackNesting(int amt) {
518 if (!mAddToBackStack) {
519 return;
520 }
521 if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting in " + this
522 + " by " + amt);
523 Op op = mHead;
524 while (op != null) {
525 op.fragment.mBackStackNesting += amt;
526 if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting of "
527 + op.fragment + " to " + op.fragment.mBackStackNesting);
528 if (op.removed != null) {
529 for (int i=op.removed.size()-1; i>=0; i--) {
530 Fragment r = op.removed.get(i);
531 r.mBackStackNesting += amt;
532 if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting of "
533 + r + " to " + r.mBackStackNesting);
534 }
535 }
536 op = op.next;
537 }
538 }
539
Dianne Hackborndd913a52010-07-22 12:17:04 -0700540 public int commit() {
Dianne Hackbornab36acb2010-11-05 14:12:11 -0700541 return commitInternal(false);
542 }
543
544 public int commitAllowingStateLoss() {
545 return commitInternal(true);
546 }
547
548 int commitInternal(boolean allowStateLoss) {
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700549 if (mCommitted) throw new IllegalStateException("commit already called");
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700550 if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Commit: " + this);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700551 mCommitted = true;
Dianne Hackborndd913a52010-07-22 12:17:04 -0700552 if (mAddToBackStack) {
553 mIndex = mManager.allocBackStackIndex(this);
554 } else {
555 mIndex = -1;
556 }
Dianne Hackbornab36acb2010-11-05 14:12:11 -0700557 mManager.enqueueAction(this, allowStateLoss);
Dianne Hackborndd913a52010-07-22 12:17:04 -0700558 return mIndex;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700559 }
Dianne Hackbornab36acb2010-11-05 14:12:11 -0700560
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700561 public void run() {
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700562 if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Run: " + this);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700563
Dianne Hackborndd913a52010-07-22 12:17:04 -0700564 if (mAddToBackStack) {
565 if (mIndex < 0) {
566 throw new IllegalStateException("addToBackStack() called after commit()");
567 }
568 }
569
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700570 bumpBackStackNesting(1);
571
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700572 Op op = mHead;
573 while (op != null) {
574 switch (op.cmd) {
575 case OP_ADD: {
576 Fragment f = op.fragment;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700577 f.mNextAnim = op.enterAnim;
578 mManager.addFragment(f, false);
579 } break;
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700580 case OP_REPLACE: {
581 Fragment f = op.fragment;
582 if (mManager.mAdded != null) {
583 for (int i=0; i<mManager.mAdded.size(); i++) {
584 Fragment old = mManager.mAdded.get(i);
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700585 if (FragmentManagerImpl.DEBUG) Log.v(TAG,
Dianne Hackborn445646c2010-06-25 15:52:59 -0700586 "OP_REPLACE: adding=" + f + " old=" + old);
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700587 if (old.mContainerId == f.mContainerId) {
588 if (op.removed == null) {
589 op.removed = new ArrayList<Fragment>();
590 }
591 op.removed.add(old);
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700592 old.mNextAnim = op.exitAnim;
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700593 if (mAddToBackStack) {
594 old.mBackStackNesting += 1;
595 if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting of "
596 + old + " to " + old.mBackStackNesting);
597 }
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700598 mManager.removeFragment(old, mTransition, mTransitionStyle);
599 }
600 }
601 }
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700602 f.mNextAnim = op.enterAnim;
603 mManager.addFragment(f, false);
604 } break;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700605 case OP_REMOVE: {
606 Fragment f = op.fragment;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700607 f.mNextAnim = op.exitAnim;
608 mManager.removeFragment(f, mTransition, mTransitionStyle);
609 } break;
610 case OP_HIDE: {
611 Fragment f = op.fragment;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700612 f.mNextAnim = op.exitAnim;
613 mManager.hideFragment(f, mTransition, mTransitionStyle);
614 } break;
615 case OP_SHOW: {
616 Fragment f = op.fragment;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700617 f.mNextAnim = op.enterAnim;
618 mManager.showFragment(f, mTransition, mTransitionStyle);
619 } break;
Dianne Hackborn47c41562011-04-15 19:00:20 -0700620 case OP_DETACH: {
621 Fragment f = op.fragment;
622 f.mNextAnim = op.exitAnim;
623 mManager.detachFragment(f, mTransition, mTransitionStyle);
624 } break;
625 case OP_ATTACH: {
626 Fragment f = op.fragment;
627 f.mNextAnim = op.enterAnim;
628 mManager.attachFragment(f, mTransition, mTransitionStyle);
629 } break;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700630 default: {
631 throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
632 }
633 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700634
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700635 op = op.next;
636 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700637
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700638 mManager.moveToState(mManager.mCurState, mTransition,
639 mTransitionStyle, true);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700640
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700641 if (mAddToBackStack) {
642 mManager.addBackStackState(this);
643 }
644 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700645
Dianne Hackborn5f36c962010-08-26 15:54:17 -0700646 public void popFromBackStack(boolean doStateMove) {
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700647 if (FragmentManagerImpl.DEBUG) Log.v(TAG, "popFromBackStack: " + this);
648
649 bumpBackStackNesting(-1);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700650
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700651 Op op = mTail;
652 while (op != null) {
653 switch (op.cmd) {
654 case OP_ADD: {
655 Fragment f = op.fragment;
Chet Haasebc377842011-03-22 11:35:22 -0700656 f.mNextAnim = op.popExitAnim;
Dianne Hackborn8952f692010-07-29 19:07:23 -0700657 f.mImmediateActivity = null;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700658 mManager.removeFragment(f,
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700659 FragmentManagerImpl.reverseTransit(mTransition),
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700660 mTransitionStyle);
661 } break;
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700662 case OP_REPLACE: {
663 Fragment f = op.fragment;
Chet Haasebc377842011-03-22 11:35:22 -0700664 f.mNextAnim = op.popExitAnim;
Dianne Hackborn8952f692010-07-29 19:07:23 -0700665 f.mImmediateActivity = null;
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700666 mManager.removeFragment(f,
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700667 FragmentManagerImpl.reverseTransit(mTransition),
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700668 mTransitionStyle);
669 if (op.removed != null) {
670 for (int i=0; i<op.removed.size(); i++) {
671 Fragment old = op.removed.get(i);
Chet Haasebc377842011-03-22 11:35:22 -0700672 old.mNextAnim = op.popEnterAnim;
Dianne Hackborn8952f692010-07-29 19:07:23 -0700673 f.mImmediateActivity = mManager.mActivity;
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700674 mManager.addFragment(old, false);
675 }
676 }
677 } break;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700678 case OP_REMOVE: {
679 Fragment f = op.fragment;
Chet Haasebc377842011-03-22 11:35:22 -0700680 f.mNextAnim = op.popEnterAnim;
Dianne Hackborn8952f692010-07-29 19:07:23 -0700681 f.mImmediateActivity = mManager.mActivity;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700682 mManager.addFragment(f, false);
683 } break;
684 case OP_HIDE: {
685 Fragment f = op.fragment;
Chet Haasebc377842011-03-22 11:35:22 -0700686 f.mNextAnim = op.popEnterAnim;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700687 mManager.showFragment(f,
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700688 FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700689 } break;
690 case OP_SHOW: {
691 Fragment f = op.fragment;
Chet Haasebc377842011-03-22 11:35:22 -0700692 f.mNextAnim = op.popExitAnim;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700693 mManager.hideFragment(f,
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700694 FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700695 } break;
Dianne Hackborn47c41562011-04-15 19:00:20 -0700696 case OP_DETACH: {
697 Fragment f = op.fragment;
698 mManager.attachFragment(f,
699 FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
700 } break;
701 case OP_ATTACH: {
702 Fragment f = op.fragment;
703 mManager.detachFragment(f,
704 FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
705 } break;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700706 default: {
707 throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
708 }
709 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700710
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700711 op = op.prev;
712 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700713
Dianne Hackborn5f36c962010-08-26 15:54:17 -0700714 if (doStateMove) {
715 mManager.moveToState(mManager.mCurState,
716 FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle, true);
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700717 }
Dianne Hackborndd913a52010-07-22 12:17:04 -0700718
719 if (mIndex >= 0) {
720 mManager.freeBackStackIndex(mIndex);
721 mIndex = -1;
722 }
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700723 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700724
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700725 public String getName() {
726 return mName;
727 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700728
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700729 public int getTransition() {
730 return mTransition;
731 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700732
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700733 public int getTransitionStyle() {
734 return mTransitionStyle;
735 }
Adam Powell2b6230e2010-09-07 17:55:25 -0700736
737 public boolean isEmpty() {
738 return mNumOp == 0;
739 }
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700740}