blob: 89ee145cbaf3baaf6a69c7d59bab869bd9420a6f [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 Hackbornf43a33c2012-09-27 00:48:11 -070023import android.util.LogWriter;
Dianne Hackborn8c841092013-06-24 13:46:13 -070024import com.android.internal.util.FastPrintWriter;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070025
Dianne Hackborn30d71892010-12-11 10:37:55 -080026import java.io.FileDescriptor;
27import java.io.PrintWriter;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070028import java.util.ArrayList;
29
30final class BackStackState implements Parcelable {
31 final int[] mOps;
32 final int mTransition;
33 final int mTransitionStyle;
34 final String mName;
Dianne Hackborndd913a52010-07-22 12:17:04 -070035 final int mIndex;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070036 final int mBreadCrumbTitleRes;
37 final CharSequence mBreadCrumbTitleText;
38 final int mBreadCrumbShortTitleRes;
39 final CharSequence mBreadCrumbShortTitleText;
40
41 public BackStackState(FragmentManagerImpl fm, BackStackRecord bse) {
Dianne Hackborn445646c2010-06-25 15:52:59 -070042 int numRemoved = 0;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070043 BackStackRecord.Op op = bse.mHead;
Dianne Hackborn445646c2010-06-25 15:52:59 -070044 while (op != null) {
45 if (op.removed != null) numRemoved += op.removed.size();
46 op = op.next;
47 }
Chet Haasebc377842011-03-22 11:35:22 -070048 mOps = new int[bse.mNumOp*7 + numRemoved];
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070049
Dianne Hackbornb7a2e472010-08-12 16:20:42 -070050 if (!bse.mAddToBackStack) {
51 throw new IllegalStateException("Not on back stack");
52 }
53
Dianne Hackborn445646c2010-06-25 15:52:59 -070054 op = bse.mHead;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070055 int pos = 0;
56 while (op != null) {
57 mOps[pos++] = op.cmd;
Dianne Hackbornee76efb2012-06-05 10:27:40 -070058 mOps[pos++] = op.fragment != null ? op.fragment.mIndex : -1;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070059 mOps[pos++] = op.enterAnim;
60 mOps[pos++] = op.exitAnim;
Chet Haasebc377842011-03-22 11:35:22 -070061 mOps[pos++] = op.popEnterAnim;
62 mOps[pos++] = op.popExitAnim;
Dianne Hackborn445646c2010-06-25 15:52:59 -070063 if (op.removed != null) {
64 final int N = op.removed.size();
65 mOps[pos++] = N;
66 for (int i=0; i<N; i++) {
67 mOps[pos++] = op.removed.get(i).mIndex;
68 }
69 } else {
70 mOps[pos++] = 0;
71 }
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070072 op = op.next;
73 }
74 mTransition = bse.mTransition;
75 mTransitionStyle = bse.mTransitionStyle;
76 mName = bse.mName;
Dianne Hackborndd913a52010-07-22 12:17:04 -070077 mIndex = bse.mIndex;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070078 mBreadCrumbTitleRes = bse.mBreadCrumbTitleRes;
79 mBreadCrumbTitleText = bse.mBreadCrumbTitleText;
80 mBreadCrumbShortTitleRes = bse.mBreadCrumbShortTitleRes;
81 mBreadCrumbShortTitleText = bse.mBreadCrumbShortTitleText;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070082 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070083
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070084 public BackStackState(Parcel in) {
85 mOps = in.createIntArray();
86 mTransition = in.readInt();
87 mTransitionStyle = in.readInt();
88 mName = in.readString();
Dianne Hackborndd913a52010-07-22 12:17:04 -070089 mIndex = in.readInt();
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070090 mBreadCrumbTitleRes = in.readInt();
91 mBreadCrumbTitleText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
92 mBreadCrumbShortTitleRes = in.readInt();
93 mBreadCrumbShortTitleText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070094 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070095
96 public BackStackRecord instantiate(FragmentManagerImpl fm) {
97 BackStackRecord bse = new BackStackRecord(fm);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070098 int pos = 0;
Dianne Hackbornf43a33c2012-09-27 00:48:11 -070099 int num = 0;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700100 while (pos < mOps.length) {
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700101 BackStackRecord.Op op = new BackStackRecord.Op();
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700102 op.cmd = mOps[pos++];
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700103 if (FragmentManagerImpl.DEBUG) Log.v(FragmentManagerImpl.TAG,
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700104 "Instantiate " + bse + " op #" + num + " base fragment #" + mOps[pos]);
Dianne Hackbornee76efb2012-06-05 10:27:40 -0700105 int findex = mOps[pos++];
106 if (findex >= 0) {
107 Fragment f = fm.mActive.get(findex);
108 op.fragment = f;
109 } else {
110 op.fragment = null;
111 }
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700112 op.enterAnim = mOps[pos++];
113 op.exitAnim = mOps[pos++];
Chet Haasebc377842011-03-22 11:35:22 -0700114 op.popEnterAnim = mOps[pos++];
115 op.popExitAnim = mOps[pos++];
Dianne Hackborn445646c2010-06-25 15:52:59 -0700116 final int N = mOps[pos++];
117 if (N > 0) {
118 op.removed = new ArrayList<Fragment>(N);
119 for (int i=0; i<N; i++) {
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700120 if (FragmentManagerImpl.DEBUG) Log.v(FragmentManagerImpl.TAG,
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700121 "Instantiate " + bse + " set remove fragment #" + mOps[pos]);
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700122 Fragment r = fm.mActive.get(mOps[pos++]);
123 op.removed.add(r);
Dianne Hackborn445646c2010-06-25 15:52:59 -0700124 }
125 }
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700126 bse.addOp(op);
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700127 num++;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700128 }
129 bse.mTransition = mTransition;
130 bse.mTransitionStyle = mTransitionStyle;
131 bse.mName = mName;
Dianne Hackborndd913a52010-07-22 12:17:04 -0700132 bse.mIndex = mIndex;
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700133 bse.mAddToBackStack = true;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700134 bse.mBreadCrumbTitleRes = mBreadCrumbTitleRes;
135 bse.mBreadCrumbTitleText = mBreadCrumbTitleText;
136 bse.mBreadCrumbShortTitleRes = mBreadCrumbShortTitleRes;
137 bse.mBreadCrumbShortTitleText = mBreadCrumbShortTitleText;
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700138 bse.bumpBackStackNesting(1);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700139 return bse;
140 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700141
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700142 public int describeContents() {
143 return 0;
144 }
145
146 public void writeToParcel(Parcel dest, int flags) {
147 dest.writeIntArray(mOps);
148 dest.writeInt(mTransition);
149 dest.writeInt(mTransitionStyle);
150 dest.writeString(mName);
Dianne Hackborndd913a52010-07-22 12:17:04 -0700151 dest.writeInt(mIndex);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700152 dest.writeInt(mBreadCrumbTitleRes);
153 TextUtils.writeToParcel(mBreadCrumbTitleText, dest, 0);
154 dest.writeInt(mBreadCrumbShortTitleRes);
155 TextUtils.writeToParcel(mBreadCrumbShortTitleText, dest, 0);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700156 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700157
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700158 public static final Parcelable.Creator<BackStackState> CREATOR
159 = new Parcelable.Creator<BackStackState>() {
160 public BackStackState createFromParcel(Parcel in) {
161 return new BackStackState(in);
162 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700163
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700164 public BackStackState[] newArray(int size) {
165 return new BackStackState[size];
166 }
167 };
168}
169
170/**
171 * @hide Entry of an operation on the fragment back stack.
172 */
Dianne Hackbornab36acb2010-11-05 14:12:11 -0700173final class BackStackRecord extends FragmentTransaction implements
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700174 FragmentManager.BackStackEntry, Runnable {
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700175 static final String TAG = FragmentManagerImpl.TAG;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700176
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700177 final FragmentManagerImpl mManager;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700178
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700179 static final int OP_NULL = 0;
180 static final int OP_ADD = 1;
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700181 static final int OP_REPLACE = 2;
182 static final int OP_REMOVE = 3;
183 static final int OP_HIDE = 4;
184 static final int OP_SHOW = 5;
Dianne Hackborn47c41562011-04-15 19:00:20 -0700185 static final int OP_DETACH = 6;
186 static final int OP_ATTACH = 7;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700187
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700188 static final class Op {
189 Op next;
190 Op prev;
191 int cmd;
192 Fragment fragment;
193 int enterAnim;
194 int exitAnim;
Chet Haasebc377842011-03-22 11:35:22 -0700195 int popEnterAnim;
196 int popExitAnim;
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700197 ArrayList<Fragment> removed;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700198 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700199
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700200 Op mHead;
201 Op mTail;
202 int mNumOp;
203 int mEnterAnim;
204 int mExitAnim;
Chet Haasebc377842011-03-22 11:35:22 -0700205 int mPopEnterAnim;
206 int mPopExitAnim;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700207 int mTransition;
208 int mTransitionStyle;
209 boolean mAddToBackStack;
Adam Powell0c24a552010-11-03 16:44:11 -0700210 boolean mAllowAddToBackStack = true;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700211 String mName;
212 boolean mCommitted;
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700213 int mIndex = -1;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700214
215 int mBreadCrumbTitleRes;
216 CharSequence mBreadCrumbTitleText;
217 int mBreadCrumbShortTitleRes;
218 CharSequence mBreadCrumbShortTitleText;
219
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700220 @Override
221 public String toString() {
222 StringBuilder sb = new StringBuilder(128);
223 sb.append("BackStackEntry{");
224 sb.append(Integer.toHexString(System.identityHashCode(this)));
225 if (mIndex >= 0) {
226 sb.append(" #");
227 sb.append(mIndex);
228 }
229 if (mName != null) {
230 sb.append(" ");
231 sb.append(mName);
232 }
233 sb.append("}");
234 return sb.toString();
235 }
236
Dianne Hackborn30d71892010-12-11 10:37:55 -0800237 public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700238 dump(prefix, writer, true);
239 }
240
241 void dump(String prefix, PrintWriter writer, boolean full) {
242 if (full) {
243 writer.print(prefix); writer.print("mName="); writer.print(mName);
244 writer.print(" mIndex="); writer.print(mIndex);
245 writer.print(" mCommitted="); writer.println(mCommitted);
246 if (mTransition != FragmentTransaction.TRANSIT_NONE) {
247 writer.print(prefix); writer.print("mTransition=#");
248 writer.print(Integer.toHexString(mTransition));
249 writer.print(" mTransitionStyle=#");
250 writer.println(Integer.toHexString(mTransitionStyle));
251 }
252 if (mEnterAnim != 0 || mExitAnim !=0) {
253 writer.print(prefix); writer.print("mEnterAnim=#");
254 writer.print(Integer.toHexString(mEnterAnim));
255 writer.print(" mExitAnim=#");
256 writer.println(Integer.toHexString(mExitAnim));
257 }
258 if (mPopEnterAnim != 0 || mPopExitAnim !=0) {
259 writer.print(prefix); writer.print("mPopEnterAnim=#");
260 writer.print(Integer.toHexString(mPopEnterAnim));
261 writer.print(" mPopExitAnim=#");
262 writer.println(Integer.toHexString(mPopExitAnim));
263 }
264 if (mBreadCrumbTitleRes != 0 || mBreadCrumbTitleText != null) {
265 writer.print(prefix); writer.print("mBreadCrumbTitleRes=#");
266 writer.print(Integer.toHexString(mBreadCrumbTitleRes));
267 writer.print(" mBreadCrumbTitleText=");
268 writer.println(mBreadCrumbTitleText);
269 }
270 if (mBreadCrumbShortTitleRes != 0 || mBreadCrumbShortTitleText != null) {
271 writer.print(prefix); writer.print("mBreadCrumbShortTitleRes=#");
272 writer.print(Integer.toHexString(mBreadCrumbShortTitleRes));
273 writer.print(" mBreadCrumbShortTitleText=");
274 writer.println(mBreadCrumbShortTitleText);
275 }
Dianne Hackborn30d71892010-12-11 10:37:55 -0800276 }
277
278 if (mHead != null) {
279 writer.print(prefix); writer.println("Operations:");
280 String innerPrefix = prefix + " ";
281 Op op = mHead;
282 int num = 0;
283 while (op != null) {
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700284 String cmdStr;
285 switch (op.cmd) {
286 case OP_NULL: cmdStr="NULL"; break;
287 case OP_ADD: cmdStr="ADD"; break;
288 case OP_REPLACE: cmdStr="REPLACE"; break;
289 case OP_REMOVE: cmdStr="REMOVE"; break;
290 case OP_HIDE: cmdStr="HIDE"; break;
291 case OP_SHOW: cmdStr="SHOW"; break;
292 case OP_DETACH: cmdStr="DETACH"; break;
293 case OP_ATTACH: cmdStr="ATTACH"; break;
294 default: cmdStr="cmd=" + op.cmd; break;
Dianne Hackborn30d71892010-12-11 10:37:55 -0800295 }
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700296 writer.print(prefix); writer.print(" Op #"); writer.print(num);
297 writer.print(": "); writer.print(cmdStr);
298 writer.print(" "); writer.println(op.fragment);
299 if (full) {
300 if (op.enterAnim != 0 || op.exitAnim != 0) {
301 writer.print(innerPrefix); writer.print("enterAnim=#");
302 writer.print(Integer.toHexString(op.enterAnim));
303 writer.print(" exitAnim=#");
304 writer.println(Integer.toHexString(op.exitAnim));
305 }
306 if (op.popEnterAnim != 0 || op.popExitAnim != 0) {
307 writer.print(innerPrefix); writer.print("popEnterAnim=#");
308 writer.print(Integer.toHexString(op.popEnterAnim));
309 writer.print(" popExitAnim=#");
310 writer.println(Integer.toHexString(op.popExitAnim));
311 }
Chet Haasebc377842011-03-22 11:35:22 -0700312 }
Dianne Hackborn30d71892010-12-11 10:37:55 -0800313 if (op.removed != null && op.removed.size() > 0) {
314 for (int i=0; i<op.removed.size(); i++) {
Dianne Hackbornd2835932010-12-13 16:28:46 -0800315 writer.print(innerPrefix);
316 if (op.removed.size() == 1) {
317 writer.print("Removed: ");
318 } else {
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700319 if (i == 0) {
320 writer.println("Removed:");
321 }
322 writer.print(innerPrefix); writer.print(" #"); writer.print(i);
Dianne Hackbornd2835932010-12-13 16:28:46 -0800323 writer.print(": ");
324 }
325 writer.println(op.removed.get(i));
Dianne Hackborn30d71892010-12-11 10:37:55 -0800326 }
327 }
328 op = op.next;
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700329 num++;
Dianne Hackborn30d71892010-12-11 10:37:55 -0800330 }
331 }
332 }
333
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700334 public BackStackRecord(FragmentManagerImpl manager) {
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700335 mManager = manager;
336 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700337
338 public int getId() {
339 return mIndex;
340 }
341
Dianne Hackborn327fbd22011-01-17 14:38:50 -0800342 public int getBreadCrumbTitleRes() {
343 return mBreadCrumbTitleRes;
344 }
345
346 public int getBreadCrumbShortTitleRes() {
347 return mBreadCrumbShortTitleRes;
348 }
349
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700350 public CharSequence getBreadCrumbTitle() {
351 if (mBreadCrumbTitleRes != 0) {
352 return mManager.mActivity.getText(mBreadCrumbTitleRes);
353 }
354 return mBreadCrumbTitleText;
355 }
356
357 public CharSequence getBreadCrumbShortTitle() {
358 if (mBreadCrumbShortTitleRes != 0) {
359 return mManager.mActivity.getText(mBreadCrumbShortTitleRes);
360 }
361 return mBreadCrumbShortTitleText;
362 }
363
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700364 void addOp(Op op) {
365 if (mHead == null) {
366 mHead = mTail = op;
367 } else {
368 op.prev = mTail;
369 mTail.next = op;
370 mTail = op;
371 }
372 op.enterAnim = mEnterAnim;
373 op.exitAnim = mExitAnim;
Chet Haasebc377842011-03-22 11:35:22 -0700374 op.popEnterAnim = mPopEnterAnim;
375 op.popExitAnim = mPopExitAnim;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700376 mNumOp++;
377 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700378
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700379 public FragmentTransaction add(Fragment fragment, String tag) {
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700380 doAddOp(0, fragment, tag, OP_ADD);
381 return this;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700382 }
383
384 public FragmentTransaction add(int containerViewId, Fragment fragment) {
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700385 doAddOp(containerViewId, fragment, null, OP_ADD);
386 return this;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700387 }
388
389 public FragmentTransaction add(int containerViewId, Fragment fragment, String tag) {
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700390 doAddOp(containerViewId, fragment, tag, OP_ADD);
391 return this;
392 }
393
394 private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) {
Dianne Hackborn3e449ce2010-09-11 20:52:31 -0700395 fragment.mFragmentManager = mManager;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700396
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700397 if (tag != null) {
398 if (fragment.mTag != null && !tag.equals(fragment.mTag)) {
399 throw new IllegalStateException("Can't change tag of fragment "
400 + fragment + ": was " + fragment.mTag
401 + " now " + tag);
402 }
403 fragment.mTag = tag;
404 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700405
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700406 if (containerViewId != 0) {
407 if (fragment.mFragmentId != 0 && fragment.mFragmentId != containerViewId) {
408 throw new IllegalStateException("Can't change container ID of fragment "
409 + fragment + ": was " + fragment.mFragmentId
410 + " now " + containerViewId);
411 }
412 fragment.mContainerId = fragment.mFragmentId = containerViewId;
413 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700414
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700415 Op op = new Op();
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700416 op.cmd = opcmd;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700417 op.fragment = fragment;
418 addOp(op);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700419 }
420
421 public FragmentTransaction replace(int containerViewId, Fragment fragment) {
422 return replace(containerViewId, fragment, null);
423 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700424
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700425 public FragmentTransaction replace(int containerViewId, Fragment fragment, String tag) {
426 if (containerViewId == 0) {
427 throw new IllegalArgumentException("Must use non-zero containerViewId");
428 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700429
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700430 doAddOp(containerViewId, fragment, tag, OP_REPLACE);
431 return this;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700432 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700433
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700434 public FragmentTransaction remove(Fragment fragment) {
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700435 Op op = new Op();
436 op.cmd = OP_REMOVE;
437 op.fragment = fragment;
438 addOp(op);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700439
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700440 return this;
441 }
442
443 public FragmentTransaction hide(Fragment fragment) {
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700444 Op op = new Op();
445 op.cmd = OP_HIDE;
446 op.fragment = fragment;
447 addOp(op);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700448
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700449 return this;
450 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700451
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700452 public FragmentTransaction show(Fragment fragment) {
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700453 Op op = new Op();
454 op.cmd = OP_SHOW;
455 op.fragment = fragment;
456 addOp(op);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700457
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700458 return this;
459 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700460
Dianne Hackborn47c41562011-04-15 19:00:20 -0700461 public FragmentTransaction detach(Fragment fragment) {
Dianne Hackborn47c41562011-04-15 19:00:20 -0700462 Op op = new Op();
463 op.cmd = OP_DETACH;
464 op.fragment = fragment;
465 addOp(op);
466
467 return this;
468 }
469
470 public FragmentTransaction attach(Fragment fragment) {
Dianne Hackborn47c41562011-04-15 19:00:20 -0700471 Op op = new Op();
472 op.cmd = OP_ATTACH;
473 op.fragment = fragment;
474 addOp(op);
475
476 return this;
477 }
478
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700479 public FragmentTransaction setCustomAnimations(int enter, int exit) {
Chet Haasebc377842011-03-22 11:35:22 -0700480 return setCustomAnimations(enter, exit, 0, 0);
481 }
482
483 public FragmentTransaction setCustomAnimations(int enter, int exit,
484 int popEnter, int popExit) {
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700485 mEnterAnim = enter;
486 mExitAnim = exit;
Chet Haasebc377842011-03-22 11:35:22 -0700487 mPopEnterAnim = popEnter;
488 mPopExitAnim = popExit;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700489 return this;
490 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700491
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700492 public FragmentTransaction setTransition(int transition) {
493 mTransition = transition;
494 return this;
495 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700496
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700497 public FragmentTransaction setTransitionStyle(int styleRes) {
498 mTransitionStyle = styleRes;
499 return this;
500 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700501
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700502 public FragmentTransaction addToBackStack(String name) {
Adam Powell0c24a552010-11-03 16:44:11 -0700503 if (!mAllowAddToBackStack) {
504 throw new IllegalStateException(
505 "This FragmentTransaction is not allowed to be added to the back stack.");
506 }
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700507 mAddToBackStack = true;
508 mName = name;
509 return this;
510 }
511
Adam Powell0c24a552010-11-03 16:44:11 -0700512 public boolean isAddToBackStackAllowed() {
513 return mAllowAddToBackStack;
514 }
515
516 public FragmentTransaction disallowAddToBackStack() {
517 if (mAddToBackStack) {
518 throw new IllegalStateException(
519 "This transaction is already being added to the back stack");
520 }
521 mAllowAddToBackStack = false;
522 return this;
523 }
524
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700525 public FragmentTransaction setBreadCrumbTitle(int res) {
526 mBreadCrumbTitleRes = res;
527 mBreadCrumbTitleText = null;
528 return this;
529 }
530
531 public FragmentTransaction setBreadCrumbTitle(CharSequence text) {
532 mBreadCrumbTitleRes = 0;
533 mBreadCrumbTitleText = text;
534 return this;
535 }
536
537 public FragmentTransaction setBreadCrumbShortTitle(int res) {
538 mBreadCrumbShortTitleRes = res;
539 mBreadCrumbShortTitleText = null;
540 return this;
541 }
542
543 public FragmentTransaction setBreadCrumbShortTitle(CharSequence text) {
544 mBreadCrumbShortTitleRes = 0;
545 mBreadCrumbShortTitleText = text;
546 return this;
547 }
548
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700549 void bumpBackStackNesting(int amt) {
550 if (!mAddToBackStack) {
551 return;
552 }
553 if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting in " + this
554 + " by " + amt);
555 Op op = mHead;
556 while (op != null) {
Dianne Hackbornee76efb2012-06-05 10:27:40 -0700557 if (op.fragment != null) {
558 op.fragment.mBackStackNesting += amt;
559 if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting of "
560 + op.fragment + " to " + op.fragment.mBackStackNesting);
561 }
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700562 if (op.removed != null) {
563 for (int i=op.removed.size()-1; i>=0; i--) {
564 Fragment r = op.removed.get(i);
565 r.mBackStackNesting += amt;
566 if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting of "
567 + r + " to " + r.mBackStackNesting);
568 }
569 }
570 op = op.next;
571 }
572 }
573
Dianne Hackborndd913a52010-07-22 12:17:04 -0700574 public int commit() {
Dianne Hackbornab36acb2010-11-05 14:12:11 -0700575 return commitInternal(false);
576 }
577
578 public int commitAllowingStateLoss() {
579 return commitInternal(true);
580 }
581
582 int commitInternal(boolean allowStateLoss) {
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700583 if (mCommitted) throw new IllegalStateException("commit already called");
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700584 if (FragmentManagerImpl.DEBUG) {
585 Log.v(TAG, "Commit: " + this);
586 LogWriter logw = new LogWriter(Log.VERBOSE, TAG);
Dianne Hackborn8c841092013-06-24 13:46:13 -0700587 PrintWriter pw = new FastPrintWriter(logw, false, 1024);
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700588 dump(" ", null, pw, null);
Dianne Hackborn8c841092013-06-24 13:46:13 -0700589 pw.flush();
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700590 }
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700591 mCommitted = true;
Dianne Hackborndd913a52010-07-22 12:17:04 -0700592 if (mAddToBackStack) {
593 mIndex = mManager.allocBackStackIndex(this);
594 } else {
595 mIndex = -1;
596 }
Dianne Hackbornab36acb2010-11-05 14:12:11 -0700597 mManager.enqueueAction(this, allowStateLoss);
Dianne Hackborndd913a52010-07-22 12:17:04 -0700598 return mIndex;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700599 }
Dianne Hackbornab36acb2010-11-05 14:12:11 -0700600
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700601 public void run() {
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700602 if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Run: " + this);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700603
Dianne Hackborndd913a52010-07-22 12:17:04 -0700604 if (mAddToBackStack) {
605 if (mIndex < 0) {
606 throw new IllegalStateException("addToBackStack() called after commit()");
607 }
608 }
609
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700610 bumpBackStackNesting(1);
611
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700612 Op op = mHead;
613 while (op != null) {
614 switch (op.cmd) {
615 case OP_ADD: {
616 Fragment f = op.fragment;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700617 f.mNextAnim = op.enterAnim;
618 mManager.addFragment(f, false);
619 } break;
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700620 case OP_REPLACE: {
621 Fragment f = op.fragment;
622 if (mManager.mAdded != null) {
623 for (int i=0; i<mManager.mAdded.size(); i++) {
624 Fragment old = mManager.mAdded.get(i);
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700625 if (FragmentManagerImpl.DEBUG) Log.v(TAG,
Dianne Hackborn445646c2010-06-25 15:52:59 -0700626 "OP_REPLACE: adding=" + f + " old=" + old);
Dianne Hackbornee76efb2012-06-05 10:27:40 -0700627 if (f == null || old.mContainerId == f.mContainerId) {
628 if (old == f) {
629 op.fragment = f = null;
630 } else {
631 if (op.removed == null) {
632 op.removed = new ArrayList<Fragment>();
633 }
634 op.removed.add(old);
635 old.mNextAnim = op.exitAnim;
636 if (mAddToBackStack) {
637 old.mBackStackNesting += 1;
638 if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting of "
639 + old + " to " + old.mBackStackNesting);
640 }
641 mManager.removeFragment(old, mTransition, mTransitionStyle);
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700642 }
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700643 }
644 }
645 }
Dianne Hackbornee76efb2012-06-05 10:27:40 -0700646 if (f != null) {
647 f.mNextAnim = op.enterAnim;
648 mManager.addFragment(f, false);
649 }
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700650 } break;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700651 case OP_REMOVE: {
652 Fragment f = op.fragment;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700653 f.mNextAnim = op.exitAnim;
654 mManager.removeFragment(f, mTransition, mTransitionStyle);
655 } break;
656 case OP_HIDE: {
657 Fragment f = op.fragment;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700658 f.mNextAnim = op.exitAnim;
659 mManager.hideFragment(f, mTransition, mTransitionStyle);
660 } break;
661 case OP_SHOW: {
662 Fragment f = op.fragment;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700663 f.mNextAnim = op.enterAnim;
664 mManager.showFragment(f, mTransition, mTransitionStyle);
665 } break;
Dianne Hackborn47c41562011-04-15 19:00:20 -0700666 case OP_DETACH: {
667 Fragment f = op.fragment;
668 f.mNextAnim = op.exitAnim;
669 mManager.detachFragment(f, mTransition, mTransitionStyle);
670 } break;
671 case OP_ATTACH: {
672 Fragment f = op.fragment;
673 f.mNextAnim = op.enterAnim;
674 mManager.attachFragment(f, mTransition, mTransitionStyle);
675 } break;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700676 default: {
677 throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
678 }
679 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700680
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700681 op = op.next;
682 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700683
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700684 mManager.moveToState(mManager.mCurState, mTransition,
685 mTransitionStyle, true);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700686
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700687 if (mAddToBackStack) {
688 mManager.addBackStackState(this);
689 }
690 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700691
Dianne Hackborn5f36c962010-08-26 15:54:17 -0700692 public void popFromBackStack(boolean doStateMove) {
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700693 if (FragmentManagerImpl.DEBUG) {
694 Log.v(TAG, "popFromBackStack: " + this);
695 LogWriter logw = new LogWriter(Log.VERBOSE, TAG);
Dianne Hackborn8c841092013-06-24 13:46:13 -0700696 PrintWriter pw = new FastPrintWriter(logw, false, 1024);
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700697 dump(" ", null, pw, null);
Dianne Hackborn8c841092013-06-24 13:46:13 -0700698 pw.flush();
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700699 }
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700700
701 bumpBackStackNesting(-1);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700702
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700703 Op op = mTail;
704 while (op != null) {
705 switch (op.cmd) {
706 case OP_ADD: {
707 Fragment f = op.fragment;
Chet Haasebc377842011-03-22 11:35:22 -0700708 f.mNextAnim = op.popExitAnim;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700709 mManager.removeFragment(f,
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700710 FragmentManagerImpl.reverseTransit(mTransition),
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700711 mTransitionStyle);
712 } break;
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700713 case OP_REPLACE: {
714 Fragment f = op.fragment;
Dianne Hackbornee76efb2012-06-05 10:27:40 -0700715 if (f != null) {
716 f.mNextAnim = op.popExitAnim;
717 mManager.removeFragment(f,
718 FragmentManagerImpl.reverseTransit(mTransition),
719 mTransitionStyle);
720 }
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700721 if (op.removed != null) {
722 for (int i=0; i<op.removed.size(); i++) {
723 Fragment old = op.removed.get(i);
Chet Haasebc377842011-03-22 11:35:22 -0700724 old.mNextAnim = op.popEnterAnim;
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700725 mManager.addFragment(old, false);
726 }
727 }
728 } break;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700729 case OP_REMOVE: {
730 Fragment f = op.fragment;
Chet Haasebc377842011-03-22 11:35:22 -0700731 f.mNextAnim = op.popEnterAnim;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700732 mManager.addFragment(f, false);
733 } break;
734 case OP_HIDE: {
735 Fragment f = op.fragment;
Chet Haasebc377842011-03-22 11:35:22 -0700736 f.mNextAnim = op.popEnterAnim;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700737 mManager.showFragment(f,
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700738 FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700739 } break;
740 case OP_SHOW: {
741 Fragment f = op.fragment;
Chet Haasebc377842011-03-22 11:35:22 -0700742 f.mNextAnim = op.popExitAnim;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700743 mManager.hideFragment(f,
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700744 FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700745 } break;
Dianne Hackborn47c41562011-04-15 19:00:20 -0700746 case OP_DETACH: {
747 Fragment f = op.fragment;
Dianne Hackbornd04ad542011-07-25 16:16:15 -0700748 f.mNextAnim = op.popEnterAnim;
Dianne Hackborn47c41562011-04-15 19:00:20 -0700749 mManager.attachFragment(f,
750 FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
751 } break;
752 case OP_ATTACH: {
753 Fragment f = op.fragment;
Dianne Hackbornd04ad542011-07-25 16:16:15 -0700754 f.mNextAnim = op.popExitAnim;
Dianne Hackborn47c41562011-04-15 19:00:20 -0700755 mManager.detachFragment(f,
756 FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
757 } break;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700758 default: {
759 throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
760 }
761 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700762
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700763 op = op.prev;
764 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700765
Dianne Hackborn5f36c962010-08-26 15:54:17 -0700766 if (doStateMove) {
767 mManager.moveToState(mManager.mCurState,
768 FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle, true);
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700769 }
Dianne Hackborndd913a52010-07-22 12:17:04 -0700770
771 if (mIndex >= 0) {
772 mManager.freeBackStackIndex(mIndex);
773 mIndex = -1;
774 }
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700775 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700776
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700777 public String getName() {
778 return mName;
779 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700780
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700781 public int getTransition() {
782 return mTransition;
783 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700784
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700785 public int getTransitionStyle() {
786 return mTransitionStyle;
787 }
Adam Powell2b6230e2010-09-07 17:55:25 -0700788
789 public boolean isEmpty() {
790 return mNumOp == 0;
791 }
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700792}