blob: 1b1d3418a5b1114deeaff3d1f545bc74aa5d305d [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 Hackborn5ae74d62010-05-19 19:14:57 -070024
Dianne Hackborn30d71892010-12-11 10:37:55 -080025import java.io.FileDescriptor;
26import java.io.PrintWriter;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070027import java.util.ArrayList;
28
29final class BackStackState implements Parcelable {
30 final int[] mOps;
31 final int mTransition;
32 final int mTransitionStyle;
33 final String mName;
Dianne Hackborndd913a52010-07-22 12:17:04 -070034 final int mIndex;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070035 final int mBreadCrumbTitleRes;
36 final CharSequence mBreadCrumbTitleText;
37 final int mBreadCrumbShortTitleRes;
38 final CharSequence mBreadCrumbShortTitleText;
39
40 public BackStackState(FragmentManagerImpl fm, BackStackRecord bse) {
Dianne Hackborn445646c2010-06-25 15:52:59 -070041 int numRemoved = 0;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070042 BackStackRecord.Op op = bse.mHead;
Dianne Hackborn445646c2010-06-25 15:52:59 -070043 while (op != null) {
44 if (op.removed != null) numRemoved += op.removed.size();
45 op = op.next;
46 }
Chet Haasebc377842011-03-22 11:35:22 -070047 mOps = new int[bse.mNumOp*7 + numRemoved];
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070048
Dianne Hackbornb7a2e472010-08-12 16:20:42 -070049 if (!bse.mAddToBackStack) {
50 throw new IllegalStateException("Not on back stack");
51 }
52
Dianne Hackborn445646c2010-06-25 15:52:59 -070053 op = bse.mHead;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070054 int pos = 0;
55 while (op != null) {
56 mOps[pos++] = op.cmd;
Dianne Hackbornee76efb2012-06-05 10:27:40 -070057 mOps[pos++] = op.fragment != null ? op.fragment.mIndex : -1;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070058 mOps[pos++] = op.enterAnim;
59 mOps[pos++] = op.exitAnim;
Chet Haasebc377842011-03-22 11:35:22 -070060 mOps[pos++] = op.popEnterAnim;
61 mOps[pos++] = op.popExitAnim;
Dianne Hackborn445646c2010-06-25 15:52:59 -070062 if (op.removed != null) {
63 final int N = op.removed.size();
64 mOps[pos++] = N;
65 for (int i=0; i<N; i++) {
66 mOps[pos++] = op.removed.get(i).mIndex;
67 }
68 } else {
69 mOps[pos++] = 0;
70 }
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070071 op = op.next;
72 }
73 mTransition = bse.mTransition;
74 mTransitionStyle = bse.mTransitionStyle;
75 mName = bse.mName;
Dianne Hackborndd913a52010-07-22 12:17:04 -070076 mIndex = bse.mIndex;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070077 mBreadCrumbTitleRes = bse.mBreadCrumbTitleRes;
78 mBreadCrumbTitleText = bse.mBreadCrumbTitleText;
79 mBreadCrumbShortTitleRes = bse.mBreadCrumbShortTitleRes;
80 mBreadCrumbShortTitleText = bse.mBreadCrumbShortTitleText;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070081 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070082
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070083 public BackStackState(Parcel in) {
84 mOps = in.createIntArray();
85 mTransition = in.readInt();
86 mTransitionStyle = in.readInt();
87 mName = in.readString();
Dianne Hackborndd913a52010-07-22 12:17:04 -070088 mIndex = in.readInt();
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070089 mBreadCrumbTitleRes = in.readInt();
90 mBreadCrumbTitleText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
91 mBreadCrumbShortTitleRes = in.readInt();
92 mBreadCrumbShortTitleText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070093 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070094
95 public BackStackRecord instantiate(FragmentManagerImpl fm) {
96 BackStackRecord bse = new BackStackRecord(fm);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070097 int pos = 0;
Dianne Hackbornf43a33c2012-09-27 00:48:11 -070098 int num = 0;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070099 while (pos < mOps.length) {
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700100 BackStackRecord.Op op = new BackStackRecord.Op();
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700101 op.cmd = mOps[pos++];
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700102 if (FragmentManagerImpl.DEBUG) Log.v(FragmentManagerImpl.TAG,
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700103 "Instantiate " + bse + " op #" + num + " base fragment #" + mOps[pos]);
Dianne Hackbornee76efb2012-06-05 10:27:40 -0700104 int findex = mOps[pos++];
105 if (findex >= 0) {
106 Fragment f = fm.mActive.get(findex);
107 op.fragment = f;
108 } else {
109 op.fragment = null;
110 }
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700111 op.enterAnim = mOps[pos++];
112 op.exitAnim = mOps[pos++];
Chet Haasebc377842011-03-22 11:35:22 -0700113 op.popEnterAnim = mOps[pos++];
114 op.popExitAnim = mOps[pos++];
Dianne Hackborn445646c2010-06-25 15:52:59 -0700115 final int N = mOps[pos++];
116 if (N > 0) {
117 op.removed = new ArrayList<Fragment>(N);
118 for (int i=0; i<N; i++) {
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700119 if (FragmentManagerImpl.DEBUG) Log.v(FragmentManagerImpl.TAG,
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700120 "Instantiate " + bse + " set remove fragment #" + mOps[pos]);
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700121 Fragment r = fm.mActive.get(mOps[pos++]);
122 op.removed.add(r);
Dianne Hackborn445646c2010-06-25 15:52:59 -0700123 }
124 }
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700125 bse.addOp(op);
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700126 num++;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700127 }
128 bse.mTransition = mTransition;
129 bse.mTransitionStyle = mTransitionStyle;
130 bse.mName = mName;
Dianne Hackborndd913a52010-07-22 12:17:04 -0700131 bse.mIndex = mIndex;
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700132 bse.mAddToBackStack = true;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700133 bse.mBreadCrumbTitleRes = mBreadCrumbTitleRes;
134 bse.mBreadCrumbTitleText = mBreadCrumbTitleText;
135 bse.mBreadCrumbShortTitleRes = mBreadCrumbShortTitleRes;
136 bse.mBreadCrumbShortTitleText = mBreadCrumbShortTitleText;
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700137 bse.bumpBackStackNesting(1);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700138 return bse;
139 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700140
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700141 public int describeContents() {
142 return 0;
143 }
144
145 public void writeToParcel(Parcel dest, int flags) {
146 dest.writeIntArray(mOps);
147 dest.writeInt(mTransition);
148 dest.writeInt(mTransitionStyle);
149 dest.writeString(mName);
Dianne Hackborndd913a52010-07-22 12:17:04 -0700150 dest.writeInt(mIndex);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700151 dest.writeInt(mBreadCrumbTitleRes);
152 TextUtils.writeToParcel(mBreadCrumbTitleText, dest, 0);
153 dest.writeInt(mBreadCrumbShortTitleRes);
154 TextUtils.writeToParcel(mBreadCrumbShortTitleText, dest, 0);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700155 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700156
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700157 public static final Parcelable.Creator<BackStackState> CREATOR
158 = new Parcelable.Creator<BackStackState>() {
159 public BackStackState createFromParcel(Parcel in) {
160 return new BackStackState(in);
161 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700162
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700163 public BackStackState[] newArray(int size) {
164 return new BackStackState[size];
165 }
166 };
167}
168
169/**
170 * @hide Entry of an operation on the fragment back stack.
171 */
Dianne Hackbornab36acb2010-11-05 14:12:11 -0700172final class BackStackRecord extends FragmentTransaction implements
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700173 FragmentManager.BackStackEntry, Runnable {
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700174 static final String TAG = FragmentManagerImpl.TAG;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700175
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700176 final FragmentManagerImpl mManager;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700177
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700178 static final int OP_NULL = 0;
179 static final int OP_ADD = 1;
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700180 static final int OP_REPLACE = 2;
181 static final int OP_REMOVE = 3;
182 static final int OP_HIDE = 4;
183 static final int OP_SHOW = 5;
Dianne Hackborn47c41562011-04-15 19:00:20 -0700184 static final int OP_DETACH = 6;
185 static final int OP_ATTACH = 7;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700186
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700187 static final class Op {
188 Op next;
189 Op prev;
190 int cmd;
191 Fragment fragment;
192 int enterAnim;
193 int exitAnim;
Chet Haasebc377842011-03-22 11:35:22 -0700194 int popEnterAnim;
195 int popExitAnim;
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700196 ArrayList<Fragment> removed;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700197 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700198
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700199 Op mHead;
200 Op mTail;
201 int mNumOp;
202 int mEnterAnim;
203 int mExitAnim;
Chet Haasebc377842011-03-22 11:35:22 -0700204 int mPopEnterAnim;
205 int mPopExitAnim;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700206 int mTransition;
207 int mTransitionStyle;
208 boolean mAddToBackStack;
Adam Powell0c24a552010-11-03 16:44:11 -0700209 boolean mAllowAddToBackStack = true;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700210 String mName;
211 boolean mCommitted;
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700212 int mIndex = -1;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700213
214 int mBreadCrumbTitleRes;
215 CharSequence mBreadCrumbTitleText;
216 int mBreadCrumbShortTitleRes;
217 CharSequence mBreadCrumbShortTitleText;
218
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700219 @Override
220 public String toString() {
221 StringBuilder sb = new StringBuilder(128);
222 sb.append("BackStackEntry{");
223 sb.append(Integer.toHexString(System.identityHashCode(this)));
224 if (mIndex >= 0) {
225 sb.append(" #");
226 sb.append(mIndex);
227 }
228 if (mName != null) {
229 sb.append(" ");
230 sb.append(mName);
231 }
232 sb.append("}");
233 return sb.toString();
234 }
235
Dianne Hackborn30d71892010-12-11 10:37:55 -0800236 public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700237 dump(prefix, writer, true);
238 }
239
240 void dump(String prefix, PrintWriter writer, boolean full) {
241 if (full) {
242 writer.print(prefix); writer.print("mName="); writer.print(mName);
243 writer.print(" mIndex="); writer.print(mIndex);
244 writer.print(" mCommitted="); writer.println(mCommitted);
245 if (mTransition != FragmentTransaction.TRANSIT_NONE) {
246 writer.print(prefix); writer.print("mTransition=#");
247 writer.print(Integer.toHexString(mTransition));
248 writer.print(" mTransitionStyle=#");
249 writer.println(Integer.toHexString(mTransitionStyle));
250 }
251 if (mEnterAnim != 0 || mExitAnim !=0) {
252 writer.print(prefix); writer.print("mEnterAnim=#");
253 writer.print(Integer.toHexString(mEnterAnim));
254 writer.print(" mExitAnim=#");
255 writer.println(Integer.toHexString(mExitAnim));
256 }
257 if (mPopEnterAnim != 0 || mPopExitAnim !=0) {
258 writer.print(prefix); writer.print("mPopEnterAnim=#");
259 writer.print(Integer.toHexString(mPopEnterAnim));
260 writer.print(" mPopExitAnim=#");
261 writer.println(Integer.toHexString(mPopExitAnim));
262 }
263 if (mBreadCrumbTitleRes != 0 || mBreadCrumbTitleText != null) {
264 writer.print(prefix); writer.print("mBreadCrumbTitleRes=#");
265 writer.print(Integer.toHexString(mBreadCrumbTitleRes));
266 writer.print(" mBreadCrumbTitleText=");
267 writer.println(mBreadCrumbTitleText);
268 }
269 if (mBreadCrumbShortTitleRes != 0 || mBreadCrumbShortTitleText != null) {
270 writer.print(prefix); writer.print("mBreadCrumbShortTitleRes=#");
271 writer.print(Integer.toHexString(mBreadCrumbShortTitleRes));
272 writer.print(" mBreadCrumbShortTitleText=");
273 writer.println(mBreadCrumbShortTitleText);
274 }
Dianne Hackborn30d71892010-12-11 10:37:55 -0800275 }
276
277 if (mHead != null) {
278 writer.print(prefix); writer.println("Operations:");
279 String innerPrefix = prefix + " ";
280 Op op = mHead;
281 int num = 0;
282 while (op != null) {
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700283 String cmdStr;
284 switch (op.cmd) {
285 case OP_NULL: cmdStr="NULL"; break;
286 case OP_ADD: cmdStr="ADD"; break;
287 case OP_REPLACE: cmdStr="REPLACE"; break;
288 case OP_REMOVE: cmdStr="REMOVE"; break;
289 case OP_HIDE: cmdStr="HIDE"; break;
290 case OP_SHOW: cmdStr="SHOW"; break;
291 case OP_DETACH: cmdStr="DETACH"; break;
292 case OP_ATTACH: cmdStr="ATTACH"; break;
293 default: cmdStr="cmd=" + op.cmd; break;
Dianne Hackborn30d71892010-12-11 10:37:55 -0800294 }
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700295 writer.print(prefix); writer.print(" Op #"); writer.print(num);
296 writer.print(": "); writer.print(cmdStr);
297 writer.print(" "); writer.println(op.fragment);
298 if (full) {
299 if (op.enterAnim != 0 || op.exitAnim != 0) {
300 writer.print(innerPrefix); writer.print("enterAnim=#");
301 writer.print(Integer.toHexString(op.enterAnim));
302 writer.print(" exitAnim=#");
303 writer.println(Integer.toHexString(op.exitAnim));
304 }
305 if (op.popEnterAnim != 0 || op.popExitAnim != 0) {
306 writer.print(innerPrefix); writer.print("popEnterAnim=#");
307 writer.print(Integer.toHexString(op.popEnterAnim));
308 writer.print(" popExitAnim=#");
309 writer.println(Integer.toHexString(op.popExitAnim));
310 }
Chet Haasebc377842011-03-22 11:35:22 -0700311 }
Dianne Hackborn30d71892010-12-11 10:37:55 -0800312 if (op.removed != null && op.removed.size() > 0) {
313 for (int i=0; i<op.removed.size(); i++) {
Dianne Hackbornd2835932010-12-13 16:28:46 -0800314 writer.print(innerPrefix);
315 if (op.removed.size() == 1) {
316 writer.print("Removed: ");
317 } else {
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700318 if (i == 0) {
319 writer.println("Removed:");
320 }
321 writer.print(innerPrefix); writer.print(" #"); writer.print(i);
Dianne Hackbornd2835932010-12-13 16:28:46 -0800322 writer.print(": ");
323 }
324 writer.println(op.removed.get(i));
Dianne Hackborn30d71892010-12-11 10:37:55 -0800325 }
326 }
327 op = op.next;
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700328 num++;
Dianne Hackborn30d71892010-12-11 10:37:55 -0800329 }
330 }
331 }
332
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700333 public BackStackRecord(FragmentManagerImpl manager) {
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700334 mManager = manager;
335 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700336
337 public int getId() {
338 return mIndex;
339 }
340
Dianne Hackborn327fbd22011-01-17 14:38:50 -0800341 public int getBreadCrumbTitleRes() {
342 return mBreadCrumbTitleRes;
343 }
344
345 public int getBreadCrumbShortTitleRes() {
346 return mBreadCrumbShortTitleRes;
347 }
348
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700349 public CharSequence getBreadCrumbTitle() {
350 if (mBreadCrumbTitleRes != 0) {
351 return mManager.mActivity.getText(mBreadCrumbTitleRes);
352 }
353 return mBreadCrumbTitleText;
354 }
355
356 public CharSequence getBreadCrumbShortTitle() {
357 if (mBreadCrumbShortTitleRes != 0) {
358 return mManager.mActivity.getText(mBreadCrumbShortTitleRes);
359 }
360 return mBreadCrumbShortTitleText;
361 }
362
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700363 void addOp(Op op) {
364 if (mHead == null) {
365 mHead = mTail = op;
366 } else {
367 op.prev = mTail;
368 mTail.next = op;
369 mTail = op;
370 }
371 op.enterAnim = mEnterAnim;
372 op.exitAnim = mExitAnim;
Chet Haasebc377842011-03-22 11:35:22 -0700373 op.popEnterAnim = mPopEnterAnim;
374 op.popExitAnim = mPopExitAnim;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700375 mNumOp++;
376 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700377
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700378 public FragmentTransaction add(Fragment fragment, String tag) {
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700379 doAddOp(0, fragment, tag, OP_ADD);
380 return this;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700381 }
382
383 public FragmentTransaction add(int containerViewId, Fragment fragment) {
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700384 doAddOp(containerViewId, fragment, null, OP_ADD);
385 return this;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700386 }
387
388 public FragmentTransaction add(int containerViewId, Fragment fragment, String tag) {
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700389 doAddOp(containerViewId, fragment, tag, OP_ADD);
390 return this;
391 }
392
393 private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) {
Dianne Hackborn3e449ce2010-09-11 20:52:31 -0700394 fragment.mFragmentManager = mManager;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700395
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700396 if (tag != null) {
397 if (fragment.mTag != null && !tag.equals(fragment.mTag)) {
398 throw new IllegalStateException("Can't change tag of fragment "
399 + fragment + ": was " + fragment.mTag
400 + " now " + tag);
401 }
402 fragment.mTag = tag;
403 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700404
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700405 if (containerViewId != 0) {
406 if (fragment.mFragmentId != 0 && fragment.mFragmentId != containerViewId) {
407 throw new IllegalStateException("Can't change container ID of fragment "
408 + fragment + ": was " + fragment.mFragmentId
409 + " now " + containerViewId);
410 }
411 fragment.mContainerId = fragment.mFragmentId = containerViewId;
412 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700413
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700414 Op op = new Op();
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700415 op.cmd = opcmd;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700416 op.fragment = fragment;
417 addOp(op);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700418 }
419
420 public FragmentTransaction replace(int containerViewId, Fragment fragment) {
421 return replace(containerViewId, fragment, null);
422 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700423
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700424 public FragmentTransaction replace(int containerViewId, Fragment fragment, String tag) {
425 if (containerViewId == 0) {
426 throw new IllegalArgumentException("Must use non-zero containerViewId");
427 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700428
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700429 doAddOp(containerViewId, fragment, tag, OP_REPLACE);
430 return this;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700431 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700432
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700433 public FragmentTransaction remove(Fragment fragment) {
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700434 Op op = new Op();
435 op.cmd = OP_REMOVE;
436 op.fragment = fragment;
437 addOp(op);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700438
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700439 return this;
440 }
441
442 public FragmentTransaction hide(Fragment fragment) {
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700443 Op op = new Op();
444 op.cmd = OP_HIDE;
445 op.fragment = fragment;
446 addOp(op);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700447
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700448 return this;
449 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700450
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700451 public FragmentTransaction show(Fragment fragment) {
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700452 Op op = new Op();
453 op.cmd = OP_SHOW;
454 op.fragment = fragment;
455 addOp(op);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700456
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700457 return this;
458 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700459
Dianne Hackborn47c41562011-04-15 19:00:20 -0700460 public FragmentTransaction detach(Fragment fragment) {
Dianne Hackborn47c41562011-04-15 19:00:20 -0700461 Op op = new Op();
462 op.cmd = OP_DETACH;
463 op.fragment = fragment;
464 addOp(op);
465
466 return this;
467 }
468
469 public FragmentTransaction attach(Fragment fragment) {
Dianne Hackborn47c41562011-04-15 19:00:20 -0700470 Op op = new Op();
471 op.cmd = OP_ATTACH;
472 op.fragment = fragment;
473 addOp(op);
474
475 return this;
476 }
477
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700478 public FragmentTransaction setCustomAnimations(int enter, int exit) {
Chet Haasebc377842011-03-22 11:35:22 -0700479 return setCustomAnimations(enter, exit, 0, 0);
480 }
481
482 public FragmentTransaction setCustomAnimations(int enter, int exit,
483 int popEnter, int popExit) {
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700484 mEnterAnim = enter;
485 mExitAnim = exit;
Chet Haasebc377842011-03-22 11:35:22 -0700486 mPopEnterAnim = popEnter;
487 mPopExitAnim = popExit;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700488 return this;
489 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700490
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700491 public FragmentTransaction setTransition(int transition) {
492 mTransition = transition;
493 return this;
494 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700495
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700496 public FragmentTransaction setTransitionStyle(int styleRes) {
497 mTransitionStyle = styleRes;
498 return this;
499 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700500
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700501 public FragmentTransaction addToBackStack(String name) {
Adam Powell0c24a552010-11-03 16:44:11 -0700502 if (!mAllowAddToBackStack) {
503 throw new IllegalStateException(
504 "This FragmentTransaction is not allowed to be added to the back stack.");
505 }
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700506 mAddToBackStack = true;
507 mName = name;
508 return this;
509 }
510
Adam Powell0c24a552010-11-03 16:44:11 -0700511 public boolean isAddToBackStackAllowed() {
512 return mAllowAddToBackStack;
513 }
514
515 public FragmentTransaction disallowAddToBackStack() {
516 if (mAddToBackStack) {
517 throw new IllegalStateException(
518 "This transaction is already being added to the back stack");
519 }
520 mAllowAddToBackStack = false;
521 return this;
522 }
523
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700524 public FragmentTransaction setBreadCrumbTitle(int res) {
525 mBreadCrumbTitleRes = res;
526 mBreadCrumbTitleText = null;
527 return this;
528 }
529
530 public FragmentTransaction setBreadCrumbTitle(CharSequence text) {
531 mBreadCrumbTitleRes = 0;
532 mBreadCrumbTitleText = text;
533 return this;
534 }
535
536 public FragmentTransaction setBreadCrumbShortTitle(int res) {
537 mBreadCrumbShortTitleRes = res;
538 mBreadCrumbShortTitleText = null;
539 return this;
540 }
541
542 public FragmentTransaction setBreadCrumbShortTitle(CharSequence text) {
543 mBreadCrumbShortTitleRes = 0;
544 mBreadCrumbShortTitleText = text;
545 return this;
546 }
547
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700548 void bumpBackStackNesting(int amt) {
549 if (!mAddToBackStack) {
550 return;
551 }
552 if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting in " + this
553 + " by " + amt);
554 Op op = mHead;
555 while (op != null) {
Dianne Hackbornee76efb2012-06-05 10:27:40 -0700556 if (op.fragment != null) {
557 op.fragment.mBackStackNesting += amt;
558 if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting of "
559 + op.fragment + " to " + op.fragment.mBackStackNesting);
560 }
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700561 if (op.removed != null) {
562 for (int i=op.removed.size()-1; i>=0; i--) {
563 Fragment r = op.removed.get(i);
564 r.mBackStackNesting += amt;
565 if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting of "
566 + r + " to " + r.mBackStackNesting);
567 }
568 }
569 op = op.next;
570 }
571 }
572
Dianne Hackborndd913a52010-07-22 12:17:04 -0700573 public int commit() {
Dianne Hackbornab36acb2010-11-05 14:12:11 -0700574 return commitInternal(false);
575 }
576
577 public int commitAllowingStateLoss() {
578 return commitInternal(true);
579 }
580
581 int commitInternal(boolean allowStateLoss) {
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700582 if (mCommitted) throw new IllegalStateException("commit already called");
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700583 if (FragmentManagerImpl.DEBUG) {
584 Log.v(TAG, "Commit: " + this);
585 LogWriter logw = new LogWriter(Log.VERBOSE, TAG);
586 PrintWriter pw = new PrintWriter(logw);
587 dump(" ", null, pw, null);
588 }
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700589 mCommitted = true;
Dianne Hackborndd913a52010-07-22 12:17:04 -0700590 if (mAddToBackStack) {
591 mIndex = mManager.allocBackStackIndex(this);
592 } else {
593 mIndex = -1;
594 }
Dianne Hackbornab36acb2010-11-05 14:12:11 -0700595 mManager.enqueueAction(this, allowStateLoss);
Dianne Hackborndd913a52010-07-22 12:17:04 -0700596 return mIndex;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700597 }
Dianne Hackbornab36acb2010-11-05 14:12:11 -0700598
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700599 public void run() {
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700600 if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Run: " + this);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700601
Dianne Hackborndd913a52010-07-22 12:17:04 -0700602 if (mAddToBackStack) {
603 if (mIndex < 0) {
604 throw new IllegalStateException("addToBackStack() called after commit()");
605 }
606 }
607
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700608 bumpBackStackNesting(1);
609
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700610 Op op = mHead;
611 while (op != null) {
612 switch (op.cmd) {
613 case OP_ADD: {
614 Fragment f = op.fragment;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700615 f.mNextAnim = op.enterAnim;
616 mManager.addFragment(f, false);
617 } break;
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700618 case OP_REPLACE: {
619 Fragment f = op.fragment;
620 if (mManager.mAdded != null) {
621 for (int i=0; i<mManager.mAdded.size(); i++) {
622 Fragment old = mManager.mAdded.get(i);
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700623 if (FragmentManagerImpl.DEBUG) Log.v(TAG,
Dianne Hackborn445646c2010-06-25 15:52:59 -0700624 "OP_REPLACE: adding=" + f + " old=" + old);
Dianne Hackbornee76efb2012-06-05 10:27:40 -0700625 if (f == null || old.mContainerId == f.mContainerId) {
626 if (old == f) {
627 op.fragment = f = null;
628 } else {
629 if (op.removed == null) {
630 op.removed = new ArrayList<Fragment>();
631 }
632 op.removed.add(old);
633 old.mNextAnim = op.exitAnim;
634 if (mAddToBackStack) {
635 old.mBackStackNesting += 1;
636 if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting of "
637 + old + " to " + old.mBackStackNesting);
638 }
639 mManager.removeFragment(old, mTransition, mTransitionStyle);
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700640 }
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700641 }
642 }
643 }
Dianne Hackbornee76efb2012-06-05 10:27:40 -0700644 if (f != null) {
645 f.mNextAnim = op.enterAnim;
646 mManager.addFragment(f, false);
647 }
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700648 } break;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700649 case OP_REMOVE: {
650 Fragment f = op.fragment;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700651 f.mNextAnim = op.exitAnim;
652 mManager.removeFragment(f, mTransition, mTransitionStyle);
653 } break;
654 case OP_HIDE: {
655 Fragment f = op.fragment;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700656 f.mNextAnim = op.exitAnim;
657 mManager.hideFragment(f, mTransition, mTransitionStyle);
658 } break;
659 case OP_SHOW: {
660 Fragment f = op.fragment;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700661 f.mNextAnim = op.enterAnim;
662 mManager.showFragment(f, mTransition, mTransitionStyle);
663 } break;
Dianne Hackborn47c41562011-04-15 19:00:20 -0700664 case OP_DETACH: {
665 Fragment f = op.fragment;
666 f.mNextAnim = op.exitAnim;
667 mManager.detachFragment(f, mTransition, mTransitionStyle);
668 } break;
669 case OP_ATTACH: {
670 Fragment f = op.fragment;
671 f.mNextAnim = op.enterAnim;
672 mManager.attachFragment(f, mTransition, mTransitionStyle);
673 } break;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700674 default: {
675 throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
676 }
677 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700678
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700679 op = op.next;
680 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700681
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700682 mManager.moveToState(mManager.mCurState, mTransition,
683 mTransitionStyle, true);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700684
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700685 if (mAddToBackStack) {
686 mManager.addBackStackState(this);
687 }
688 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700689
Dianne Hackborn5f36c962010-08-26 15:54:17 -0700690 public void popFromBackStack(boolean doStateMove) {
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700691 if (FragmentManagerImpl.DEBUG) {
692 Log.v(TAG, "popFromBackStack: " + this);
693 LogWriter logw = new LogWriter(Log.VERBOSE, TAG);
694 PrintWriter pw = new PrintWriter(logw);
695 dump(" ", null, pw, null);
696 }
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700697
698 bumpBackStackNesting(-1);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700699
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700700 Op op = mTail;
701 while (op != null) {
702 switch (op.cmd) {
703 case OP_ADD: {
704 Fragment f = op.fragment;
Chet Haasebc377842011-03-22 11:35:22 -0700705 f.mNextAnim = op.popExitAnim;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700706 mManager.removeFragment(f,
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700707 FragmentManagerImpl.reverseTransit(mTransition),
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700708 mTransitionStyle);
709 } break;
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700710 case OP_REPLACE: {
711 Fragment f = op.fragment;
Dianne Hackbornee76efb2012-06-05 10:27:40 -0700712 if (f != null) {
713 f.mNextAnim = op.popExitAnim;
714 mManager.removeFragment(f,
715 FragmentManagerImpl.reverseTransit(mTransition),
716 mTransitionStyle);
717 }
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700718 if (op.removed != null) {
719 for (int i=0; i<op.removed.size(); i++) {
720 Fragment old = op.removed.get(i);
Chet Haasebc377842011-03-22 11:35:22 -0700721 old.mNextAnim = op.popEnterAnim;
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700722 mManager.addFragment(old, false);
723 }
724 }
725 } break;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700726 case OP_REMOVE: {
727 Fragment f = op.fragment;
Chet Haasebc377842011-03-22 11:35:22 -0700728 f.mNextAnim = op.popEnterAnim;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700729 mManager.addFragment(f, false);
730 } break;
731 case OP_HIDE: {
732 Fragment f = op.fragment;
Chet Haasebc377842011-03-22 11:35:22 -0700733 f.mNextAnim = op.popEnterAnim;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700734 mManager.showFragment(f,
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700735 FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700736 } break;
737 case OP_SHOW: {
738 Fragment f = op.fragment;
Chet Haasebc377842011-03-22 11:35:22 -0700739 f.mNextAnim = op.popExitAnim;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700740 mManager.hideFragment(f,
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700741 FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700742 } break;
Dianne Hackborn47c41562011-04-15 19:00:20 -0700743 case OP_DETACH: {
744 Fragment f = op.fragment;
Dianne Hackbornd04ad542011-07-25 16:16:15 -0700745 f.mNextAnim = op.popEnterAnim;
Dianne Hackborn47c41562011-04-15 19:00:20 -0700746 mManager.attachFragment(f,
747 FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
748 } break;
749 case OP_ATTACH: {
750 Fragment f = op.fragment;
Dianne Hackbornd04ad542011-07-25 16:16:15 -0700751 f.mNextAnim = op.popExitAnim;
Dianne Hackborn47c41562011-04-15 19:00:20 -0700752 mManager.detachFragment(f,
753 FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
754 } break;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700755 default: {
756 throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
757 }
758 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700759
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700760 op = op.prev;
761 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700762
Dianne Hackborn5f36c962010-08-26 15:54:17 -0700763 if (doStateMove) {
764 mManager.moveToState(mManager.mCurState,
765 FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle, true);
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700766 }
Dianne Hackborndd913a52010-07-22 12:17:04 -0700767
768 if (mIndex >= 0) {
769 mManager.freeBackStackIndex(mIndex);
770 mIndex = -1;
771 }
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700772 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700773
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700774 public String getName() {
775 return mName;
776 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700777
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700778 public int getTransition() {
779 return mTransition;
780 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700781
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700782 public int getTransitionStyle() {
783 return mTransitionStyle;
784 }
Adam Powell2b6230e2010-09-07 17:55:25 -0700785
786 public boolean isEmpty() {
787 return mNumOp == 0;
788 }
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700789}