FragmentManager.java revision 464b6f3c93dda03359ec2d37c8205065922f2994
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2011 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 58451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * you may not use this file except in compliance with the License. 68451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * You may obtain a copy of the License at 78451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 98451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 118451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 128451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * See the License for the specific language governing permissions and 148451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.support.v4.app; 18f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn 19f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackbornimport android.content.Context; 20f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackbornimport android.content.res.Configuration; 21f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackbornimport android.os.Bundle; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Looper; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcel; 25ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlettimport android.os.Parcelable; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.support.v4.util.DebugUtils; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.support.v4.util.LogWriter; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.SparseArray; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.animation.AccelerateInterpolator; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.animation.AlphaAnimation; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.animation.Animation; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.animation.AnimationSet; 34ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlettimport android.view.animation.AnimationUtils; 350c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Feltimport android.view.animation.DecelerateInterpolator; 36f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Feltimport android.view.animation.Interpolator; 370c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Feltimport android.view.animation.ScaleAnimation; 380c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Feltimport android.view.animation.Animation.AnimationListener; 395c13d89c1332fcc499379b9064b891187b75ca32Chet Haaseimport android.view.Menu; 400c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Feltimport android.view.MenuInflater; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.MenuItem; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewGroup; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Arrays; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Static library support version of the framework's {@link android.app.FragmentManager}. 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Used to write apps that run on platforms prior to Android 3.0. When running 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on Android 3.0 or above, this implementation is still used; it does not try 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to switch to the framework's implementation. See the framework SDK 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * documentation for a class overview. 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Your activity must derive from {@link FragmentActivity} to use this. 583d63e0119dc763ed0a06fd7498375746fd391d80Mike Reed */ 59c511bee87cda99a252d1a62487f47c8f05aee78cFabrice Di Megliopublic abstract class FragmentManager { 60c511bee87cda99a252d1a62487f47c8f05aee78cFabrice Di Meglio /** 613d63e0119dc763ed0a06fd7498375746fd391d80Mike Reed * Representation of an entry on the fragment back stack, as created 623d63e0119dc763ed0a06fd7498375746fd391d80Mike Reed * with {@link FragmentTransaction#addToBackStack(String) 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * FragmentTransaction.addToBackStack()}. Entries can later be 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * retrieved with {@link FragmentManager#getBackStackEntryAt(int) 650c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt * FragmentManager.getBackStackEntry()}. 660c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt * 670c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt * <p>Note that you should never hold on to a BackStackEntry object; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the identifier as returned by {@link #getId} is the only thing that 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will be persisted across activity instances. 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface BackStackEntry { 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the unique identifier for the entry. This is the only 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * representation of the entry that will persist across activity 753d63e0119dc763ed0a06fd7498375746fd391d80Mike Reed * instances. 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getId(); 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Get the name that was supplied to 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link FragmentTransaction#addToBackStack(String) 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * FragmentTransaction.addToBackStack(String)} when creating this entry. 838451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes */ 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String getName(); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 863d63e0119dc763ed0a06fd7498375746fd391d80Mike Reed /** 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the full bread crumb title resource identifier for the entry, 888451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * or 0 if it does not have one. 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getBreadCrumbTitleRes(); 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 928451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes /** 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the short bread crumb title resource identifier for the entry, 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or 0 if it does not have one. 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getBreadCrumbShortTitleRes(); 978451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the full bread crumb title for the entry, or null if it 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * does not have one. 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1028451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes public CharSequence getBreadCrumbTitle(); 103f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn 104f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn /** 105f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn * Return the short bread crumb title for the entry, or null if it 106f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn * does not have one. 107f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn */ 108f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn public CharSequence getBreadCrumbShortTitle(); 109f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn } 110f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn 111f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn /** 112f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn * Interface to watch for changes to the back stack. 113f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn */ 114f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn public interface OnBackStackChangedListener { 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called whenever the contents of the back stack change. 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onBackStackChanged(); 1198451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes } 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Start a series of edit operations on the Fragments associated with 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this FragmentManager. 1248451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Note: A fragment transaction can only be created/committed prior 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to an activity saving its state. If you try to commit a transaction 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * after {@link FragmentActivity#onSaveInstanceState FragmentActivity.onSaveInstanceState()} 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * (and prior to a following {@link FragmentActivity#onStart FragmentActivity.onStart} 1298451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * or {@link FragmentActivity#onResume FragmentActivity.onResume()}, you will get an error. 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is because the framework takes care of saving your current fragments 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the state, and if changes are made after the state is saved then they 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will be lost.</p> 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1348451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes public abstract FragmentTransaction beginTransaction(); 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide -- remove once prebuilts are in. */ 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public FragmentTransaction openTransaction() { 1398451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes return beginTransaction(); 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * After a {@link FragmentTransaction} is committed with 1448451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * {@link FragmentTransaction#commit FragmentTransaction.commit()}, it 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is scheduled to be executed asynchronously on the process's main thread. 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If you want to immediately executing any such pending operations, you 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * can call this function (only from the main thread) to do so. Note that 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * all callbacks and other related behavior will be done from within this 1498451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * call, so be careful about where this is called from. 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns true if there were any pending transactions to be 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * executed. 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1548451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes public abstract boolean executePendingTransactions(); 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Finds a fragment that was identified by the given id either when inflated 1588451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * from XML or as the container ID when added in a transaction. This first 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * searches through fragments that are currently added to the manager's 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * activity; if no such fragment is found, then all fragments currently 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on the back stack associated with this ID are searched. 1628451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * @return The fragment if found or null otherwise. 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public abstract Fragment findFragmentById(int id); 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1678451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * Finds a fragment that was identified by the given tag either when inflated 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * from XML or as supplied when added in a transaction. This first 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * searches through fragments that are currently added to the manager's 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * activity; if no such fragment is found, then all fragments currently 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on the back stack are searched. 1728451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * @return The fragment if found or null otherwise. 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public abstract Fragment findFragmentByTag(String tag); 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1778451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * Flag for {@link #popBackStack(String, int)} 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and {@link #popBackStack(int, int)}: If set, and the name or ID of 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a back stack entry has been supplied, then all matching entries will 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * be consumed until one that doesn't match is found or the bottom of 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the stack is reached. Otherwise, all entries up to but not including that entry 1828451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * will be removed. 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int POP_BACK_STACK_INCLUSIVE = 1<<0; 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1878451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * Pop the top state off the back stack. Returns true if there was one 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to pop, else false. This function is asynchronous -- it enqueues the 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * request to pop, but the action will not be performed until the application 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * returns to its event loop. 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1928451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes public abstract void popBackStack(); 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Like {@link #popBackStack()}, but performs the operation immediately 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * inside of the call. This is like calling {@link #executePendingTransactions()} 1978451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * afterwards. 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns true if there was something popped, else false. 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public abstract boolean popBackStackImmediate(); 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2028451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes /** 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Pop the last fragment transition from the manager's fragment 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * back stack. If there is nothing to pop, false is returned. 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This function is asynchronous -- it enqueues the 2068451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * request to pop, but the action will not be performed until the application 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * returns to its event loop. 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param name If non-null, this is the name of a previous back state 2108451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * to look for; if found, all states up to that state will be popped. The 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #POP_BACK_STACK_INCLUSIVE} flag can be used to control whether 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the named state itself is popped. If null, only the top state is popped. 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param flags Either 0 or {@link #POP_BACK_STACK_INCLUSIVE}. 2148451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes */ 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public abstract void popBackStack(String name, int flags); 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2188451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * Like {@link #popBackStack(String, int)}, but performs the operation immediately 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * inside of the call. This is like calling {@link #executePendingTransactions()} 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * afterwards. 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns true if there was something popped, else false. 2228451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes */ 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public abstract boolean popBackStackImmediate(String name, int flags); 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2268451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * Pop all back stack states up to the one with the given identifier. 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This function is asynchronous -- it enqueues the 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * request to pop, but the action will not be performed until the application 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * returns to its event loop. 2308451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param id Identifier of the stated to be popped. If no identifier exists, 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * false is returned. 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The identifier is the number returned by 2348451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * {@link FragmentTransaction#commit() FragmentTransaction.commit()}. The 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #POP_BACK_STACK_INCLUSIVE} flag can be used to control whether 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the named state itself is popped. 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param flags Either 0 or {@link #POP_BACK_STACK_INCLUSIVE}. 2388451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes */ 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public abstract void popBackStack(int id, int flags); 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2428451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * Like {@link #popBackStack(int, int)}, but performs the operation immediately 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * inside of the call. This is like calling {@link #executePendingTransactions()} 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * afterwards. 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns true if there was something popped, else false. 2468451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes */ 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public abstract boolean popBackStackImmediate(int id, int flags); 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2508451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * Return the number of entries currently in the back stack. 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public abstract int getBackStackEntryCount(); 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2548451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes /** 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the BackStackEntry at index <var>index</var> in the back stack; 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * entries start index 0 being the bottom of the stack. 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2588451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes public abstract BackStackEntry getBackStackEntryAt(int index); 259ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett 260ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett /** 261ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett * Add a new listener for changes to the fragment back stack. 262ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett */ 263ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett public abstract void addOnBackStackChangedListener(OnBackStackChangedListener listener); 264ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett 265ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett /** 266ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett * Remove a listener that was previously added with 267ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett * {@link #addOnBackStackChangedListener(OnBackStackChangedListener)}. 268ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett */ 269ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett public abstract void removeOnBackStackChangedListener(OnBackStackChangedListener listener); 270ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett 271ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett /** 272ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett * Put a reference to a fragment in a Bundle. This Bundle can be 273ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett * persisted as saved state, and when later restoring 274ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett * {@link #getFragment(Bundle, String)} will return the current 275ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett * instance of the same fragment. 276ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett * 277ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett * @param bundle The bundle in which to put the fragment reference. 278ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett * @param key The name of the entry in the bundle. 279ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett * @param fragment The Fragment whose reference is to be stored. 280ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett */ 281ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett public abstract void putFragment(Bundle bundle, String key, Fragment fragment); 282ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett 283ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett /** 284ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett * Retrieve the current Fragment instance for a reference previously 285ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett * placed with {@link #putFragment(Bundle, String, Fragment)}. 286ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett * 287ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett * @param bundle The bundle from which to retrieve the fragment reference. 288ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett * @param key The name of the entry in the bundle. 289ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett * @return Returns the current Fragment instance that is associated with 290ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett * the given reference. 291ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett */ 292ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett public abstract Fragment getFragment(Bundle bundle, String key); 293ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett 294ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett /** 295ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett * Save the current instance state of the given Fragment. This can be 296ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett * used later when creating a new instance of the Fragment and adding 297ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett * it to the fragment manager, to have it create itself to match the 298ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett * current state returned here. Note that there are limits on how 299517825f1a9f14f92908bd7859b91b927c2eec6d9Fabrice Di Meglio * this can be used: 300ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett * 301ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett * <ul> 302ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett * <li>The Fragment must currently be attached to the FragmentManager. 303ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett * <li>A new Fragment created using this saved state must be the same class 304517825f1a9f14f92908bd7859b91b927c2eec6d9Fabrice Di Meglio * type as the Fragment it was created from. 305517825f1a9f14f92908bd7859b91b927c2eec6d9Fabrice Di Meglio * <li>The saved state can not contain dependencies on other fragments -- 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that is it can't use {@link #putFragment(Bundle, String, Fragment)} to 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * store a fragment reference because that reference may not be valid when 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this saved state is later used. Likewise the Fragment's target and 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * result code are not included in this state. 3108451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * </ul> 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param f The Fragment whose state is to be saved. 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The generated state. This will be null if there was no 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * interesting state created by the fragment. 3158451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes */ 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public abstract Fragment.SavedState saveFragmentInstanceState(Fragment f); 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Print the FragmentManager's state into the given stream. 3208451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param prefix Text to print at the front of each line. 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param fd The raw file descriptor that the dump is being sent to. 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param writer A PrintWriter to which the dump is to be set. 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param args Additional arguments to the dump request. 3258451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes */ 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public abstract void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args); 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Control whether the framework's internal fragment manager debugging 3308451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * logs are turned on. If enabled, you will see output in logcat as 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the framework performs fragment operations. 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void enableDebugLogging(boolean enabled) { 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FragmentManagerImpl.DEBUG = enabled; 3358451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes } 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectfinal class FragmentManagerState implements Parcelable { 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FragmentState[] mActive; 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] mAdded; 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BackStackState[] mBackStack; 3428451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public FragmentManagerState() { 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public FragmentManagerState(Parcel in) { 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mActive = in.createTypedArray(FragmentState.CREATOR); 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAdded = in.createIntArray(); 3498451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes mBackStack = in.createTypedArray(BackStackState.CREATOR); 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int describeContents() { 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void writeToParcel(Parcel dest, int flags) { 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest.writeTypedArray(mActive, flags); 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest.writeIntArray(mAdded); 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest.writeTypedArray(mBackStack, flags); 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final Parcelable.Creator<FragmentManagerState> CREATOR 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = new Parcelable.Creator<FragmentManagerState>() { 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public FragmentManagerState createFromParcel(Parcel in) { 3658451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes return new FragmentManagerState(in); 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public FragmentManagerState[] newArray(int size) { 3698451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes return new FragmentManagerState[size]; 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Container for fragments associated with an activity. 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectfinal class FragmentManagerImpl extends FragmentManager { 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static boolean DEBUG = false; 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final String TAG = "FragmentManager"; 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean HONEYCOMB = android.os.Build.VERSION.SDK_INT >= 11; 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final String TARGET_REQUEST_CODE_STATE_TAG = "android:target_req_state"; 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final String TARGET_STATE_TAG = "android:target_state"; 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final String VIEW_STATE_TAG = "android:view_state"; 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final String USER_VISIBLE_HINT_TAG = "android:user_visible_hint"; 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Runnable> mPendingActions; 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Runnable[] mTmpActions; 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mExecutingActions; 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3928451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes ArrayList<Fragment> mActive; 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Fragment> mAdded; 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Integer> mAvailIndices; 3956ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio ArrayList<BackStackRecord> mBackStack; 3966ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio ArrayList<Fragment> mCreatedMenus; 3976ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Must be accessed while locked. 3994f810c8535055bd9a8d89a7d1ba0a7c712a8843dFabrice Di Meglio ArrayList<BackStackRecord> mBackStackIndices; 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Integer> mAvailBackStackIndices; 4014f810c8535055bd9a8d89a7d1ba0a7c712a8843dFabrice Di Meglio 402b02d0ca5553300063e4332192632312600caf4b9Fabrice Di Meglio ArrayList<OnBackStackChangedListener> mBackStackChangeListeners; 4038fb507171f68d4170cfeb1187ee7d1f70f98917dFabrice Di Meglio 40479df5323e7ed541b854cea5684a89e8be8c2dfc9Fabrice Di Meglio int mCurState = Fragment.INITIALIZING; 405b02d0ca5553300063e4332192632312600caf4b9Fabrice Di Meglio FragmentActivity mActivity; 4064f810c8535055bd9a8d89a7d1ba0a7c712a8843dFabrice Di Meglio 4074f810c8535055bd9a8d89a7d1ba0a7c712a8843dFabrice Di Meglio boolean mNeedMenuInvalidate; 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mStateSaved; 4098451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes boolean mDestroyed; 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String mNoTransactionsBecause; 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mHavePendingDeferredStart; 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4138451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes // Temporary vars for state save and restore. 41451f383d65f9ee3c7d73d0508b576550e7998c5b5Fabrice Di Meglio Bundle mStateBundle = null; 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SparseArray<Parcelable> mStateArray = null; 41651f383d65f9ee3c7d73d0508b576550e7998c5b5Fabrice Di Meglio 4176ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio Runnable mExecCommit = new Runnable() { 4186ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio @Override 4196ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio public void run() { 4206ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio execPendingActions(); 4216ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio } 4226ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio }; 4236ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio 4246ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio @Override 4256ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio public FragmentTransaction beginTransaction() { 4264f810c8535055bd9a8d89a7d1ba0a7c712a8843dFabrice Di Meglio return new BackStackRecord(this); 4278451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes } 42851f383d65f9ee3c7d73d0508b576550e7998c5b5Fabrice Di Meglio 42979df5323e7ed541b854cea5684a89e8be8c2dfc9Fabrice Di Meglio @Override 4304f810c8535055bd9a8d89a7d1ba0a7c712a8843dFabrice Di Meglio public boolean executePendingTransactions() { 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return execPendingActions(); 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4348451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes @Override 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void popBackStack() { 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enqueueAction(new Runnable() { 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override public void run() { 4388451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes popBackStackState(mActivity.mHandler, null, -1, 0); 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4406ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio }, false); 4416ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio } 4426ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio 4436ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio @Override 4446ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio public boolean popBackStackImmediate() { 4456ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio checkStateLoss(); 4464f810c8535055bd9a8d89a7d1ba0a7c712a8843dFabrice Di Meglio executePendingTransactions(); 4476ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio return popBackStackState(mActivity.mHandler, null, -1, 0); 4488fb507171f68d4170cfeb1187ee7d1f70f98917dFabrice Di Meglio } 44979df5323e7ed541b854cea5684a89e8be8c2dfc9Fabrice Di Meglio 450b02d0ca5553300063e4332192632312600caf4b9Fabrice Di Meglio @Override 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void popBackStack(final String name, final int flags) { 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enqueueAction(new Runnable() { 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override public void run() { 4548451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes popBackStackState(mActivity.mHandler, name, -1, flags); 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4566ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio }, false); 4576ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio } 4586ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio 4596ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio @Override 4606ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio public boolean popBackStackImmediate(String name, int flags) { 4616ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio checkStateLoss(); 4626ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio executePendingTransactions(); 4636ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio return popBackStackState(mActivity.mHandler, name, -1, flags); 4646ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio } 4656ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio 4666ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio @Override 4676ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio public void popBackStack(final int id, final int flags) { 4686ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio if (id < 0) { 4696ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio throw new IllegalArgumentException("Bad id: " + id); 4706ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio } 4716ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio enqueueAction(new Runnable() { 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override public void run() { 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project popBackStackState(mActivity.mHandler, null, id, flags); 4746ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio } 4758fb507171f68d4170cfeb1187ee7d1f70f98917dFabrice Di Meglio }, false); 47679df5323e7ed541b854cea5684a89e8be8c2dfc9Fabrice Di Meglio } 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean popBackStackImmediate(int id, int flags) { 4808451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes checkStateLoss(); 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project executePendingTransactions(); 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (id < 0) { 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Bad id: " + id); 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4858451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes return popBackStackState(mActivity.mHandler, null, id, flags); 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4888451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes @Override 4899f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio public int getBackStackEntryCount() { 4909f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio return mBackStack != null ? mBackStack.size() : 0; 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public BackStackEntry getBackStackEntryAt(int index) { 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBackStack.get(index); 4960c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt } 4979f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio 4989f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio @Override 4996ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio public void addOnBackStackChangedListener(OnBackStackChangedListener listener) { 5006ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio if (mBackStackChangeListeners == null) { 5016ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio mBackStackChangeListeners = new ArrayList<OnBackStackChangedListener>(); 5026ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio } 5036ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio mBackStackChangeListeners.add(listener); 5046ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio } 5056ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio 5066ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio @Override 5076ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio public void removeOnBackStackChangedListener(OnBackStackChangedListener listener) { 5086ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio if (mBackStackChangeListeners != null) { 5096ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio mBackStackChangeListeners.remove(listener); 5106ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio } 5116ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio } 5126ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio 5136ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio @Override 5146ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio public void putFragment(Bundle bundle, String key, Fragment fragment) { 5159f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio if (fragment.mIndex < 0) { 5165c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio throw new IllegalStateException("Fragment " + fragment 517a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio + " is not currently in the FragmentManager"); 518a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio } 519a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio bundle.putInt(key, fragment.mIndex); 520a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio } 5215c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio 5225c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio @Override 523eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio public Fragment getFragment(Bundle bundle, String key) { 5245c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio int index = bundle.getInt(key, -1); 5259f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio if (index == -1) { 5269f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio return null; 5279f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio } 5289f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio if (index >= mActive.size()) { 5299f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio throw new IllegalStateException("Fragement no longer exists for key " 5309f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio + key + ": index " + index); 5319f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio } 5329f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio Fragment f = mActive.get(index); 5339f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio if (f == null) { 5349f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio throw new IllegalStateException("Fragement no longer exists for key " 5359f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio + key + ": index " + index); 5369f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio } 537f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt return f; 538f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt } 5390c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt 5406ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio @Override 5416ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio public Fragment.SavedState saveFragmentInstanceState(Fragment fragment) { 5426ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio if (fragment.mIndex < 0) { 5436ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio throw new IllegalStateException("Fragment " + fragment 5446ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio + " is not currently in the FragmentManager"); 5456ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio } 5466ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio if (fragment.mState > Fragment.INITIALIZING) { 5476ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio Bundle result = saveFragmentBasicState(fragment); 5486ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio return result != null ? new Fragment.SavedState(result) : null; 5496ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio } 5506ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio return null; 5516ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio } 5526ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio 5536ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio @Override 5546ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio public String toString() { 5556ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio StringBuilder sb = new StringBuilder(128); 5566ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio sb.append("FragmentManager{"); 5570c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt sb.append(Integer.toHexString(System.identityHashCode(this))); 5586ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio sb.append(" in "); 5590c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt DebugUtils.buildShortClassTag(mActivity, sb); 560f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt sb.append("}}"); 56179df5323e7ed541b854cea5684a89e8be8c2dfc9Fabrice Di Meglio return sb.toString(); 5620c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt } 5630c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt 5640c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt @Override 5650c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { 5660c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt String innerPrefix = prefix + " "; 5670c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt 5680c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt int N; 569eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio if (mActive != null) { 570eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio N = mActive.size(); 571eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio if (N > 0) { 5726ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio writer.print(prefix); writer.print("Active Fragments in "); 5736ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio writer.print(Integer.toHexString(System.identityHashCode(this))); 5746ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio writer.println(":"); 5756ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio for (int i=0; i<N; i++) { 5766ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio Fragment f = mActive.get(i); 5776ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio writer.print(prefix); writer.print(" #"); writer.print(i); 5786ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio writer.print(": "); writer.println(f); 5796ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio if (f != null) { 5806ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio f.dump(innerPrefix, fd, writer, args); 5816ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio } 5826ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio } 5836ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio } 5846ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio } 5856ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio 5866ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio if (mAdded != null) { 5876ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio N = mAdded.size(); 5886ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio if (N > 0) { 5896ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio writer.print(prefix); writer.println("Added Fragments:"); 590eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio for (int i=0; i<N; i++) { 5916ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio Fragment f = mAdded.get(i); 592eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio writer.print(prefix); writer.print(" #"); writer.print(i); 593eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio writer.print(": "); writer.println(f.toString()); 594eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio } 595eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio } 596eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio } 597eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio 598eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio if (mCreatedMenus != null) { 599eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio N = mCreatedMenus.size(); 600eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio if (N > 0) { 601eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio writer.print(prefix); writer.println("Fragments Created Menus:"); 6020a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio for (int i=0; i<N; i++) { 6030c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt Fragment f = mCreatedMenus.get(i); 6040a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio writer.print(prefix); writer.print(" #"); writer.print(i); 6050c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt writer.print(": "); writer.println(f.toString()); 6060a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio } 6070a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio } 6080a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio } 6090a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio 6100a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio if (mBackStack != null) { 6110c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt N = mBackStack.size(); 6120c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt if (N > 0) { 6130c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt writer.print(prefix); writer.println("Back Stack:"); 6140c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt for (int i=0; i<N; i++) { 6150a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio BackStackRecord bs = mBackStack.get(i); 6160c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt writer.print(prefix); writer.print(" #"); writer.print(i); 6170a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio writer.print(": "); writer.println(bs.toString()); 6180c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt bs.dump(innerPrefix, fd, writer, args); 6190a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio } 6200a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio } 6210a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio } 6220a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio 6230a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio synchronized (this) { 624eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio if (mBackStackIndices != null) { 625eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio N = mBackStackIndices.size(); 626eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio if (N > 0) { 627eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio writer.print(prefix); writer.println("Back Stack Indices:"); 6280c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt for (int i=0; i<N; i++) { 6290c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt BackStackRecord bs = mBackStackIndices.get(i); 6304f810c8535055bd9a8d89a7d1ba0a7c712a8843dFabrice Di Meglio writer.print(prefix); writer.print(" #"); writer.print(i); 6319c418dbc56efd334c68872d281f75138e16eae46Fabrice Di Meglio writer.print(": "); writer.println(bs); 6324f810c8535055bd9a8d89a7d1ba0a7c712a8843dFabrice Di Meglio } 63379df5323e7ed541b854cea5684a89e8be8c2dfc9Fabrice Di Meglio } 6340c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt } 6350c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt 6360c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt if (mAvailBackStackIndices != null && mAvailBackStackIndices.size() > 0) { 6370c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt writer.print(prefix); writer.print("mAvailBackStackIndices: "); 6380c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt writer.println(Arrays.toString(mAvailBackStackIndices.toArray())); 6390c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt } 6400c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt } 6410c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt 6420c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt if (mPendingActions != null) { 6430c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt N = mPendingActions.size(); 6440c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt if (N > 0) { 6450c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt writer.print(prefix); writer.println("Pending Actions:"); 6460c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt for (int i=0; i<N; i++) { 6470c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt Runnable r = mPendingActions.get(i); 6480c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt writer.print(prefix); writer.print(" #"); writer.print(i); 6490c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt writer.print(": "); writer.println(r); 6500c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt } 6510c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt } 6520c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt } 6530c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt 6540c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt writer.print(prefix); writer.println("FragmentManager misc state:"); 6550c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt writer.print(prefix); writer.print(" mCurState="); writer.print(mCurState); 6560c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt writer.print(" mStateSaved="); writer.print(mStateSaved); 6570c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt writer.print(" mDestroyed="); writer.println(mDestroyed); 6580c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt if (mNeedMenuInvalidate) { 6590c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt writer.print(prefix); writer.print(" mNeedMenuInvalidate="); 6600c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt writer.println(mNeedMenuInvalidate); 6610c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt } 6620c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt if (mNoTransactionsBecause != null) { 6630c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt writer.print(prefix); writer.print(" mNoTransactionsBecause="); 6640c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt writer.println(mNoTransactionsBecause); 6650c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt } 6660c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt if (mAvailIndices != null && mAvailIndices.size() > 0) { 6670c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt writer.print(prefix); writer.print(" mAvailIndices: "); 6680c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt writer.println(Arrays.toString(mAvailIndices.toArray())); 6690c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt } 6700c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt } 6710c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt 6720c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt static final Interpolator DECELERATE_QUINT = new DecelerateInterpolator(2.5f); 6730c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt static final Interpolator DECELERATE_CUBIC = new DecelerateInterpolator(1.5f); 6740c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt static final Interpolator ACCELERATE_QUINT = new AccelerateInterpolator(2.5f); 6750c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt static final Interpolator ACCELERATE_CUBIC = new AccelerateInterpolator(1.5f); 6760c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt 6770c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt static final int ANIM_DUR = 220; 6780c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt 6790c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt static Animation makeOpenCloseAnimation(Context context, float startScale, 6800c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt float endScale, float startAlpha, float endAlpha) { 6810c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt AnimationSet set = new AnimationSet(false); 6820c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt ScaleAnimation scale = new ScaleAnimation(startScale, endScale, startScale, endScale, 6830c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt Animation.RELATIVE_TO_SELF, .5f, Animation.RELATIVE_TO_SELF, .5f); 6840c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt scale.setInterpolator(DECELERATE_QUINT); 6850c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt scale.setDuration(ANIM_DUR); 6860c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt set.addAnimation(scale); 6870c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt AlphaAnimation alpha = new AlphaAnimation(startAlpha, endAlpha); 6880c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt alpha.setInterpolator(DECELERATE_CUBIC); 6890c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt alpha.setDuration(ANIM_DUR); 690f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt set.addAnimation(alpha); 691f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt return set; 692f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt } 693f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt 694f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt static Animation makeFadeAnimation(Context context, float start, float end) { 695f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt AlphaAnimation anim = new AlphaAnimation(start, end); 696f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt anim.setInterpolator(DECELERATE_CUBIC); 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project anim.setDuration(ANIM_DUR); 698f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt return anim; 699f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt } 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 701f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt Animation loadAnimation(Fragment fragment, int transit, boolean enter, 702f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt int transitionStyle) { 703f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt Animation animObj = fragment.onCreateAnimation(transit, enter, 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fragment.mNextAnim); 705f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt if (animObj != null) { 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return animObj; 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 708f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fragment.mNextAnim != 0) { 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Animation anim = AnimationUtils.loadAnimation(mActivity, fragment.mNextAnim); 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (anim != null) { 7128451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes return anim; 7138451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes } 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (transit == 0) { 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int styleIndex = transitToStyleIndex(transit, enter); 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (styleIndex < 0) { 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 725bd901dee317d10c6a921922c3d7d788b90306c82Fabrice Di Meglio switch (styleIndex) { 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case ANIM_STYLE_OPEN_ENTER: 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return makeOpenCloseAnimation(mActivity, 1.125f, 1.0f, 0, 1); 728a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio case ANIM_STYLE_OPEN_EXIT: 729a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio return makeOpenCloseAnimation(mActivity, 1.0f, .975f, 1, 0); 730bd901dee317d10c6a921922c3d7d788b90306c82Fabrice Di Meglio case ANIM_STYLE_CLOSE_ENTER: 731a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio return makeOpenCloseAnimation(mActivity, .975f, 1.0f, 0, 1); 732bd901dee317d10c6a921922c3d7d788b90306c82Fabrice Di Meglio case ANIM_STYLE_CLOSE_EXIT: 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return makeOpenCloseAnimation(mActivity, 1.0f, 1.075f, 1, 0); 734bd901dee317d10c6a921922c3d7d788b90306c82Fabrice Di Meglio case ANIM_STYLE_FADE_ENTER: 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return makeFadeAnimation(mActivity, 0, 1); 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case ANIM_STYLE_FADE_EXIT: 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return makeFadeAnimation(mActivity, 1, 0); 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (transitionStyle == 0 && mActivity.getWindow() != null) { 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project transitionStyle = mActivity.getWindow().getAttributes().windowAnimations; 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (transitionStyle == 0) { 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //TypedArray attrs = mActivity.obtainStyledAttributes(transitionStyle, 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // com.android.internal.R.styleable.FragmentAnimation); 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //int anim = attrs.getResourceId(styleIndex, 0); 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //attrs.recycle(); 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //if (anim == 0) { 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // return null; 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //} 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //return AnimatorInflater.loadAnimator(mActivity, anim); 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void performPendingDeferredStart(Fragment f) { 7618451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes if (f.mDeferStart) { 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mExecutingActions) { 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Wait until we're done executing our pending transactions 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHavePendingDeferredStart = true; 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.mDeferStart = false; 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project moveToState(f, mCurState, 0, 0, false); 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void moveToState(Fragment f, int newState, int transit, int transitionStyle, 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean keepActive) { 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Fragments that are not currently added will sit in the onCreate() state. 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!f.mAdded && newState > Fragment.CREATED) { 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newState = Fragment.CREATED; 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (f.mRemoving && newState > f.mState) { 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // While removing a fragment, we can't change it to a higher state. 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newState = f.mState; 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Defer start if requested; don't allow it to move to STARTED or higher 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if it's not already started. 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (f.mDeferStart && f.mState < Fragment.STARTED && newState > Fragment.STOPPED) { 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newState = Fragment.STOPPED; 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (f.mState < newState) { 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // For fragments that are created from a layout, when restoring from 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // state we don't want to allow them to be created until they are 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // being reloaded from the layout. 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (f.mFromLayout && !f.mInLayout) { 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (f.mAnimatingAway != null) { 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The fragment is currently being animated... but! Now we 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // want to move our state back up. Give up on waiting for the 7978451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes // animation, move to whatever the final state should be once 798a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio // the animation is done, and then we can proceed from there. 799a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio f.mAnimatingAway = null; 800bd901dee317d10c6a921922c3d7d788b90306c82Fabrice Di Meglio moveToState(f, f.mStateAfterAnimating, 0, 0, true); 801a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio } 802bd901dee317d10c6a921922c3d7d788b90306c82Fabrice Di Meglio switch (f.mState) { 803bd901dee317d10c6a921922c3d7d788b90306c82Fabrice Di Meglio case Fragment.INITIALIZING: 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "moveto CREATED: " + f); 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (f.mSavedFragmentState != null) { 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray( 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FragmentManagerImpl.VIEW_STATE_TAG); 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.mTarget = getFragment(f.mSavedFragmentState, 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FragmentManagerImpl.TARGET_STATE_TAG); 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (f.mTarget != null) { 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.mTargetRequestCode = f.mSavedFragmentState.getInt( 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0); 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.mUserVisibleHint = f.mSavedFragmentState.getBoolean( 8158451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true); 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!f.mUserVisibleHint) { 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.mDeferStart = true; 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newState > Fragment.STOPPED) { 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newState = Fragment.STOPPED; 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.mActivity = mActivity; 8248451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes f.mFragmentManager = mActivity.mFragments; 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.mCalled = false; 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.onAttach(mActivity); 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!f.mCalled) { 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SuperNotCalledException("Fragment " + f 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " did not call through to super.onAttach()"); 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mActivity.onAttachFragment(f); 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!f.mRetaining) { 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.mCalled = false; 835f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn f.onCreate(f.mSavedFragmentState); 836f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn if (!f.mCalled) { 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SuperNotCalledException("Fragment " + f 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " did not call through to super.onCreate()"); 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.mRetaining = false; 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (f.mFromLayout) { 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // For fragments that are part of the content view 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // layout, we need to instantiate the view immediately 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and the inflater will take care of adding it. 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.mView = f.onCreateView(f.getLayoutInflater(f.mSavedFragmentState), 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project null, f.mSavedFragmentState); 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (f.mView != null) { 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.mInnerView = f.mView; 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.mView = NoSaveStateFrameLayout.wrap(f.mView); 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (f.mHidden) f.mView.setVisibility(View.GONE); 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.onViewCreated(f.mView, f.mSavedFragmentState); 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.mInnerView = null; 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Fragment.CREATED: 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newState > Fragment.CREATED) { 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f); 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!f.mFromLayout) { 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ViewGroup container = null; 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (f.mContainerId != 0) { 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project container = (ViewGroup)mActivity.findViewById(f.mContainerId); 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (container == null && !f.mRestored) { 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("No view found for id 0x" 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Integer.toHexString(f.mContainerId) 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " for fragment " + f); 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 869517825f1a9f14f92908bd7859b91b927c2eec6d9Fabrice Di Meglio } 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.mContainer = container; 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.mView = f.onCreateView(f.getLayoutInflater(f.mSavedFragmentState), 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project container, f.mSavedFragmentState); 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (f.mView != null) { 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.mInnerView = f.mView; 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.mView = NoSaveStateFrameLayout.wrap(f.mView); 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (container != null) { 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Animation anim = loadAnimation(f, transit, true, 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project transitionStyle); 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (anim != null) { 880afa78967b8553443aa32579d78970a076d7581f6Dianne Hackborn f.mView.startAnimation(anim); 881afa78967b8553443aa32579d78970a076d7581f6Dianne Hackborn } 882afa78967b8553443aa32579d78970a076d7581f6Dianne Hackborn container.addView(f.mView); 883afa78967b8553443aa32579d78970a076d7581f6Dianne Hackborn } 884afa78967b8553443aa32579d78970a076d7581f6Dianne Hackborn if (f.mHidden) f.mView.setVisibility(View.GONE); 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.onViewCreated(f.mView, f.mSavedFragmentState); 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8870a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio f.mInnerView = null; 8880a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio } 8890a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio } 8900a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio 8910a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio f.mCalled = false; 8920a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio f.onActivityCreated(f.mSavedFragmentState); 8939f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio if (!f.mCalled) { 8949f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio throw new SuperNotCalledException("Fragment " + f 8950c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt + " did not call through to super.onActivityCreated()"); 8960c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt } 8970c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt if (f.mView != null) { 898f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt f.restoreViewState(); 899f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt } 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.mSavedFragmentState = null; 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Fragment.ACTIVITY_CREATED: 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Fragment.STOPPED: 9041e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy if (newState > Fragment.STOPPED) { 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "moveto STARTED: " + f); 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.mCalled = false; 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.performStart(); 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!f.mCalled) { 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SuperNotCalledException("Fragment " + f 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " did not call through to super.onStart()"); 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Fragment.STARTED: 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newState > Fragment.STARTED) { 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f); 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.mCalled = false; 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.mResumed = true; 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.onResume(); 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!f.mCalled) { 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SuperNotCalledException("Fragment " + f 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " did not call through to super.onResume()"); 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.mSavedFragmentState = null; 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.mSavedViewState = null; 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (f.mState > newState) { 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (f.mState) { 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Fragment.RESUMED: 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newState < Fragment.RESUMED) { 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "movefrom RESUMED: " + f); 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.mCalled = false; 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.onPause(); 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!f.mCalled) { 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SuperNotCalledException("Fragment " + f 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " did not call through to super.onPause()"); 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f.mResumed = false; 939 } 940 case Fragment.STARTED: 941 if (newState < Fragment.STARTED) { 942 if (DEBUG) Log.v(TAG, "movefrom STARTED: " + f); 943 f.mCalled = false; 944 f.performStop(); 945 if (!f.mCalled) { 946 throw new SuperNotCalledException("Fragment " + f 947 + " did not call through to super.onStop()"); 948 } 949 } 950 case Fragment.STOPPED: 951 if (newState < Fragment.STOPPED) { 952 if (DEBUG) Log.v(TAG, "movefrom STOPPED: " + f); 953 f.performReallyStop(); 954 } 955 case Fragment.ACTIVITY_CREATED: 956 if (newState < Fragment.ACTIVITY_CREATED) { 957 if (DEBUG) Log.v(TAG, "movefrom ACTIVITY_CREATED: " + f); 958 if (f.mView != null) { 959 // Need to save the current view state if not 960 // done already. 961 if (!mActivity.isFinishing() && f.mSavedViewState == null) { 962 saveFragmentViewState(f); 963 } 964 } 965 f.mCalled = false; 966 f.performDestroyView(); 967 if (!f.mCalled) { 968 throw new SuperNotCalledException("Fragment " + f 969 + " did not call through to super.onDestroyView()"); 970 } 971 if (f.mView != null && f.mContainer != null) { 972 Animation anim = null; 973 if (mCurState > Fragment.INITIALIZING && !mDestroyed) { 974 anim = loadAnimation(f, transit, false, 975 transitionStyle); 976 } 977 if (anim != null) { 978 final Fragment fragment = f; 979 f.mAnimatingAway = f.mView; 980 f.mStateAfterAnimating = newState; 981 anim.setAnimationListener(new AnimationListener() { 982 @Override 983 public void onAnimationEnd(Animation animation) { 984 if (fragment.mAnimatingAway != null) { 985 fragment.mAnimatingAway = null; 986 moveToState(fragment, fragment.mStateAfterAnimating, 987 0, 0, false); 988 } 989 } 990 @Override 991 public void onAnimationRepeat(Animation animation) { 992 } 993 @Override 994 public void onAnimationStart(Animation animation) { 995 } 996 }); 997 f.mView.startAnimation(anim); 998 } 999 f.mContainer.removeView(f.mView); 1000 } 1001 f.mContainer = null; 1002 f.mView = null; 1003 f.mInnerView = null; 1004 } 1005 case Fragment.CREATED: 1006 if (newState < Fragment.CREATED) { 1007 if (mDestroyed) { 1008 if (f.mAnimatingAway != null) { 1009 // The fragment's containing activity is 1010 // being destroyed, but this fragment is 1011 // currently animating away. Stop the 1012 // animation right now -- it is not needed, 1013 // and we can't wait any more on destroying 1014 // the fragment. 1015 View v = f.mAnimatingAway; 1016 f.mAnimatingAway = null; 1017 v.clearAnimation(); 1018 } 1019 } 1020 if (f.mAnimatingAway != null) { 1021 // We are waiting for the fragment's view to finish 1022 // animating away. Just make a note of the state 1023 // the fragment now should move to once the animation 1024 // is done. 1025 f.mStateAfterAnimating = newState; 1026 newState = Fragment.CREATED; 1027 } else { 1028 if (DEBUG) Log.v(TAG, "movefrom CREATED: " + f); 1029 if (!f.mRetaining) { 1030 f.mCalled = false; 1031 f.onDestroy(); 1032 if (!f.mCalled) { 1033 throw new SuperNotCalledException("Fragment " + f 1034 + " did not call through to super.onDestroy()"); 1035 } 1036 } 1037 1038 f.mCalled = false; 1039 f.onDetach(); 1040 if (!f.mCalled) { 1041 throw new SuperNotCalledException("Fragment " + f 1042 + " did not call through to super.onDetach()"); 1043 } 1044 if (!keepActive) { 1045 if (!f.mRetaining) { 1046 makeInactive(f); 1047 } else { 1048 f.mActivity = null; 1049 f.mFragmentManager = null; 1050 } 1051 } 1052 } 1053 } 1054 } 1055 } 1056 1057 f.mState = newState; 1058 } 1059 1060 void moveToState(Fragment f) { 1061 moveToState(f, mCurState, 0, 0, false); 1062 } 1063 1064 void moveToState(int newState, boolean always) { 1065 moveToState(newState, 0, 0, always); 1066 } 1067 1068 void moveToState(int newState, int transit, int transitStyle, boolean always) { 1069 if (mActivity == null && newState != Fragment.INITIALIZING) { 1070 throw new IllegalStateException("No activity"); 1071 } 1072 1073 if (!always && mCurState == newState) { 1074 return; 1075 } 1076 1077 mCurState = newState; 1078 if (mActive != null) { 1079 boolean loadersRunning = false; 1080 for (int i=0; i<mActive.size(); i++) { 1081 Fragment f = mActive.get(i); 1082 if (f != null) { 1083 moveToState(f, newState, transit, transitStyle, false); 1084 if (f.mLoaderManager != null) { 1085 loadersRunning |= f.mLoaderManager.hasRunningLoaders(); 1086 } 1087 } 1088 } 1089 1090 if (!loadersRunning) { 1091 startPendingDeferredFragments(); 1092 } 1093 1094 if (mNeedMenuInvalidate && mActivity != null && mCurState == Fragment.RESUMED) { 1095 mActivity.supportInvalidateOptionsMenu(); 1096 mNeedMenuInvalidate = false; 1097 } 1098 } 1099 } 1100 1101 void startPendingDeferredFragments() { 1102 if (mActive == null) return; 1103 1104 for (int i=0; i<mActive.size(); i++) { 1105 Fragment f = mActive.get(i); 1106 if (f != null) { 1107 performPendingDeferredStart(f); 1108 } 1109 } 1110 } 1111 1112 void makeActive(Fragment f) { 1113 if (f.mIndex >= 0) { 1114 return; 1115 } 1116 1117 if (mAvailIndices == null || mAvailIndices.size() <= 0) { 1118 if (mActive == null) { 1119 mActive = new ArrayList<Fragment>(); 1120 } 1121 f.setIndex(mActive.size()); 1122 mActive.add(f); 1123 1124 } else { 1125 f.setIndex(mAvailIndices.remove(mAvailIndices.size()-1)); 1126 mActive.set(f.mIndex, f); 1127 } 1128 if (DEBUG) Log.v(TAG, "Allocated fragment index " + f); 1129 } 1130 1131 void makeInactive(Fragment f) { 1132 if (f.mIndex < 0) { 1133 return; 1134 } 1135 1136 if (DEBUG) Log.v(TAG, "Freeing fragment index " + f); 1137 mActive.set(f.mIndex, null); 1138 if (mAvailIndices == null) { 1139 mAvailIndices = new ArrayList<Integer>(); 1140 } 1141 mAvailIndices.add(f.mIndex); 1142 mActivity.invalidateSupportFragmentIndex(f.mIndex); 1143 f.initState(); 1144 } 1145 1146 public void addFragment(Fragment fragment, boolean moveToStateNow) { 1147 if (mAdded == null) { 1148 mAdded = new ArrayList<Fragment>(); 1149 } 1150 if (DEBUG) Log.v(TAG, "add: " + fragment); 1151 makeActive(fragment); 1152 if (!fragment.mDetached) { 1153 mAdded.add(fragment); 1154 fragment.mAdded = true; 1155 fragment.mRemoving = false; 1156 if (fragment.mHasMenu && fragment.mMenuVisible) { 1157 mNeedMenuInvalidate = true; 1158 } 1159 if (moveToStateNow) { 1160 moveToState(fragment); 1161 } 1162 } 1163 } 1164 1165 public void removeFragment(Fragment fragment, int transition, int transitionStyle) { 1166 if (DEBUG) Log.v(TAG, "remove: " + fragment + " nesting=" + fragment.mBackStackNesting); 1167 final boolean inactive = !fragment.isInBackStack(); 1168 if (!fragment.mDetached || inactive) { 1169 if (mAdded != null) { 1170 mAdded.remove(fragment); 1171 } 1172 if (fragment.mHasMenu && fragment.mMenuVisible) { 1173 mNeedMenuInvalidate = true; 1174 } 1175 fragment.mAdded = false; 1176 fragment.mRemoving = true; 1177 moveToState(fragment, inactive ? Fragment.INITIALIZING : Fragment.CREATED, 1178 transition, transitionStyle, false); 1179 } 1180 } 1181 1182 public void hideFragment(Fragment fragment, int transition, int transitionStyle) { 1183 if (DEBUG) Log.v(TAG, "hide: " + fragment); 1184 if (!fragment.mHidden) { 1185 fragment.mHidden = true; 1186 if (fragment.mView != null) { 1187 Animation anim = loadAnimation(fragment, transition, true, 1188 transitionStyle); 1189 if (anim != null) { 1190 fragment.mView.startAnimation(anim); 1191 } 1192 fragment.mView.setVisibility(View.GONE); 1193 } 1194 if (fragment.mAdded && fragment.mHasMenu && fragment.mMenuVisible) { 1195 mNeedMenuInvalidate = true; 1196 } 1197 fragment.onHiddenChanged(true); 1198 } 1199 } 1200 1201 public void showFragment(Fragment fragment, int transition, int transitionStyle) { 1202 if (DEBUG) Log.v(TAG, "show: " + fragment); 1203 if (fragment.mHidden) { 1204 fragment.mHidden = false; 1205 if (fragment.mView != null) { 1206 Animation anim = loadAnimation(fragment, transition, true, 1207 transitionStyle); 1208 if (anim != null) { 1209 fragment.mView.startAnimation(anim); 1210 } 1211 fragment.mView.setVisibility(View.VISIBLE); 1212 } 1213 if (fragment.mAdded && fragment.mHasMenu && fragment.mMenuVisible) { 1214 mNeedMenuInvalidate = true; 1215 } 1216 fragment.onHiddenChanged(false); 1217 } 1218 } 1219 1220 public void detachFragment(Fragment fragment, int transition, int transitionStyle) { 1221 if (DEBUG) Log.v(TAG, "detach: " + fragment); 1222 if (!fragment.mDetached) { 1223 fragment.mDetached = true; 1224 if (fragment.mAdded) { 1225 // We are not already in back stack, so need to remove the fragment. 1226 if (mAdded != null) { 1227 mAdded.remove(fragment); 1228 } 1229 if (fragment.mHasMenu && fragment.mMenuVisible) { 1230 mNeedMenuInvalidate = true; 1231 } 1232 fragment.mAdded = false; 1233 moveToState(fragment, Fragment.CREATED, transition, transitionStyle, false); 1234 } 1235 } 1236 } 1237 1238 public void attachFragment(Fragment fragment, int transition, int transitionStyle) { 1239 if (DEBUG) Log.v(TAG, "attach: " + fragment); 1240 if (fragment.mDetached) { 1241 fragment.mDetached = false; 1242 if (!fragment.mAdded) { 1243 if (mAdded == null) { 1244 mAdded = new ArrayList<Fragment>(); 1245 } 1246 mAdded.add(fragment); 1247 fragment.mAdded = true; 1248 if (fragment.mHasMenu && fragment.mMenuVisible) { 1249 mNeedMenuInvalidate = true; 1250 } 1251 moveToState(fragment, mCurState, transition, transitionStyle, false); 1252 } 1253 } 1254 } 1255 1256 public Fragment findFragmentById(int id) { 1257 if (mAdded != null) { 1258 // First look through added fragments. 1259 for (int i=mAdded.size()-1; i>=0; i--) { 1260 Fragment f = mAdded.get(i); 1261 if (f != null && f.mFragmentId == id) { 1262 return f; 1263 } 1264 } 1265 } 1266 if (mActive != null) { 1267 // Now for any known fragment. 1268 for (int i=mActive.size()-1; i>=0; i--) { 1269 Fragment f = mActive.get(i); 1270 if (f != null && f.mFragmentId == id) { 1271 return f; 1272 } 1273 } 1274 } 1275 return null; 1276 } 1277 1278 public Fragment findFragmentByTag(String tag) { 1279 if (mAdded != null && tag != null) { 1280 // First look through added fragments. 1281 for (int i=mAdded.size()-1; i>=0; i--) { 1282 Fragment f = mAdded.get(i); 1283 if (f != null && tag.equals(f.mTag)) { 1284 return f; 1285 } 1286 } 1287 } 1288 if (mActive != null && tag != null) { 1289 // Now for any known fragment. 1290 for (int i=mActive.size()-1; i>=0; i--) { 1291 Fragment f = mActive.get(i); 1292 if (f != null && tag.equals(f.mTag)) { 1293 return f; 1294 } 1295 } 1296 } 1297 return null; 1298 } 1299 1300 public Fragment findFragmentByWho(String who) { 1301 if (mActive != null && who != null) { 1302 for (int i=mActive.size()-1; i>=0; i--) { 1303 Fragment f = mActive.get(i); 1304 if (f != null && who.equals(f.mWho)) { 1305 return f; 1306 } 1307 } 1308 } 1309 return null; 1310 } 1311 1312 private void checkStateLoss() { 1313 if (mStateSaved) { 1314 throw new IllegalStateException( 1315 "Can not perform this action after onSaveInstanceState"); 1316 } 1317 if (mNoTransactionsBecause != null) { 1318 throw new IllegalStateException( 1319 "Can not perform this action inside of " + mNoTransactionsBecause); 1320 } 1321 } 1322 1323 public void enqueueAction(Runnable action, boolean allowStateLoss) { 1324 if (!allowStateLoss) { 1325 checkStateLoss(); 1326 } 1327 synchronized (this) { 1328 if (mActivity == null) { 1329 throw new IllegalStateException("Activity has been destroyed"); 1330 } 1331 if (mPendingActions == null) { 1332 mPendingActions = new ArrayList<Runnable>(); 1333 } 1334 mPendingActions.add(action); 1335 if (mPendingActions.size() == 1) { 1336 mActivity.mHandler.removeCallbacks(mExecCommit); 1337 mActivity.mHandler.post(mExecCommit); 1338 } 1339 } 1340 } 1341 1342 public int allocBackStackIndex(BackStackRecord bse) { 1343 synchronized (this) { 1344 if (mAvailBackStackIndices == null || mAvailBackStackIndices.size() <= 0) { 1345 if (mBackStackIndices == null) { 1346 mBackStackIndices = new ArrayList<BackStackRecord>(); 1347 } 1348 int index = mBackStackIndices.size(); 1349 if (DEBUG) Log.v(TAG, "Setting back stack index " + index + " to " + bse); 1350 mBackStackIndices.add(bse); 1351 return index; 1352 1353 } else { 1354 int index = mAvailBackStackIndices.remove(mAvailBackStackIndices.size()-1); 1355 if (DEBUG) Log.v(TAG, "Adding back stack index " + index + " with " + bse); 1356 mBackStackIndices.set(index, bse); 1357 return index; 1358 } 1359 } 1360 } 1361 1362 public void setBackStackIndex(int index, BackStackRecord bse) { 1363 synchronized (this) { 1364 if (mBackStackIndices == null) { 1365 mBackStackIndices = new ArrayList<BackStackRecord>(); 1366 } 1367 int N = mBackStackIndices.size(); 1368 if (index < N) { 1369 if (DEBUG) Log.v(TAG, "Setting back stack index " + index + " to " + bse); 1370 mBackStackIndices.set(index, bse); 1371 } else { 1372 while (N < index) { 1373 mBackStackIndices.add(null); 1374 if (mAvailBackStackIndices == null) { 1375 mAvailBackStackIndices = new ArrayList<Integer>(); 1376 } 1377 if (DEBUG) Log.v(TAG, "Adding available back stack index " + N); 1378 mAvailBackStackIndices.add(N); 1379 N++; 1380 } 1381 if (DEBUG) Log.v(TAG, "Adding back stack index " + index + " with " + bse); 1382 mBackStackIndices.add(bse); 1383 } 1384 } 1385 } 1386 1387 public void freeBackStackIndex(int index) { 1388 synchronized (this) { 1389 mBackStackIndices.set(index, null); 1390 if (mAvailBackStackIndices == null) { 1391 mAvailBackStackIndices = new ArrayList<Integer>(); 1392 } 1393 if (DEBUG) Log.v(TAG, "Freeing back stack index " + index); 1394 mAvailBackStackIndices.add(index); 1395 } 1396 } 1397 1398 /** 1399 * Only call from main thread! 1400 */ 1401 public boolean execPendingActions() { 1402 if (mExecutingActions) { 1403 throw new IllegalStateException("Recursive entry to executePendingTransactions"); 1404 } 1405 1406 if (Looper.myLooper() != mActivity.mHandler.getLooper()) { 1407 throw new IllegalStateException("Must be called from main thread of process"); 1408 } 1409 1410 boolean didSomething = false; 1411 1412 while (true) { 1413 int numActions; 1414 1415 synchronized (this) { 1416 if (mPendingActions == null || mPendingActions.size() == 0) { 1417 break; 1418 } 1419 1420 numActions = mPendingActions.size(); 1421 if (mTmpActions == null || mTmpActions.length < numActions) { 1422 mTmpActions = new Runnable[numActions]; 1423 } 1424 mPendingActions.toArray(mTmpActions); 1425 mPendingActions.clear(); 1426 mActivity.mHandler.removeCallbacks(mExecCommit); 1427 } 1428 1429 mExecutingActions = true; 1430 for (int i=0; i<numActions; i++) { 1431 mTmpActions[i].run(); 1432 mTmpActions[i] = null; 1433 } 1434 mExecutingActions = false; 1435 didSomething = true; 1436 } 1437 1438 if (mHavePendingDeferredStart) { 1439 boolean loadersRunning = false; 1440 for (int i=0; i<mActive.size(); i++) { 1441 Fragment f = mActive.get(i); 1442 if (f != null && f.mLoaderManager != null) { 1443 loadersRunning |= f.mLoaderManager.hasRunningLoaders(); 1444 } 1445 } 1446 if (!loadersRunning) { 1447 mHavePendingDeferredStart = false; 1448 startPendingDeferredFragments(); 1449 } 1450 } 1451 return didSomething; 1452 } 1453 1454 void reportBackStackChanged() { 1455 if (mBackStackChangeListeners != null) { 1456 for (int i=0; i<mBackStackChangeListeners.size(); i++) { 1457 mBackStackChangeListeners.get(i).onBackStackChanged(); 1458 } 1459 } 1460 } 1461 1462 void addBackStackState(BackStackRecord state) { 1463 if (mBackStack == null) { 1464 mBackStack = new ArrayList<BackStackRecord>(); 1465 } 1466 mBackStack.add(state); 1467 reportBackStackChanged(); 1468 } 1469 1470 boolean popBackStackState(Handler handler, String name, int id, int flags) { 1471 if (mBackStack == null) { 1472 return false; 1473 } 1474 if (name == null && id < 0 && (flags&POP_BACK_STACK_INCLUSIVE) == 0) { 1475 int last = mBackStack.size()-1; 1476 if (last < 0) { 1477 return false; 1478 } 1479 final BackStackRecord bss = mBackStack.remove(last); 1480 bss.popFromBackStack(true); 1481 reportBackStackChanged(); 1482 } else { 1483 int index = -1; 1484 if (name != null || id >= 0) { 1485 // If a name or ID is specified, look for that place in 1486 // the stack. 1487 index = mBackStack.size()-1; 1488 while (index >= 0) { 1489 BackStackRecord bss = mBackStack.get(index); 1490 if (name != null && name.equals(bss.getName())) { 1491 break; 1492 } 1493 if (id >= 0 && id == bss.mIndex) { 1494 break; 1495 } 1496 index--; 1497 } 1498 if (index < 0) { 1499 return false; 1500 } 1501 if ((flags&POP_BACK_STACK_INCLUSIVE) != 0) { 1502 index--; 1503 // Consume all following entries that match. 1504 while (index >= 0) { 1505 BackStackRecord bss = mBackStack.get(index); 1506 if ((name != null && name.equals(bss.getName())) 1507 || (id >= 0 && id == bss.mIndex)) { 1508 index--; 1509 continue; 1510 } 1511 break; 1512 } 1513 } 1514 } 1515 if (index == mBackStack.size()-1) { 1516 return false; 1517 } 1518 final ArrayList<BackStackRecord> states 1519 = new ArrayList<BackStackRecord>(); 1520 for (int i=mBackStack.size()-1; i>index; i--) { 1521 states.add(mBackStack.remove(i)); 1522 } 1523 final int LAST = states.size()-1; 1524 for (int i=0; i<=LAST; i++) { 1525 if (DEBUG) Log.v(TAG, "Popping back stack state: " + states.get(i)); 1526 states.get(i).popFromBackStack(i == LAST); 1527 } 1528 reportBackStackChanged(); 1529 } 1530 return true; 1531 } 1532 1533 ArrayList<Fragment> retainNonConfig() { 1534 ArrayList<Fragment> fragments = null; 1535 if (mActive != null) { 1536 for (int i=0; i<mActive.size(); i++) { 1537 Fragment f = mActive.get(i); 1538 if (f != null && f.mRetainInstance) { 1539 if (fragments == null) { 1540 fragments = new ArrayList<Fragment>(); 1541 } 1542 fragments.add(f); 1543 f.mRetaining = true; 1544 f.mTargetIndex = f.mTarget != null ? f.mTarget.mIndex : -1; 1545 if (DEBUG) Log.v(TAG, "retainNonConfig: keeping retained " + f); 1546 } 1547 } 1548 } 1549 return fragments; 1550 } 1551 1552 void saveFragmentViewState(Fragment f) { 1553 if (f.mInnerView == null) { 1554 return; 1555 } 1556 if (mStateArray == null) { 1557 mStateArray = new SparseArray<Parcelable>(); 1558 } else { 1559 mStateArray.clear(); 1560 } 1561 f.mInnerView.saveHierarchyState(mStateArray); 1562 if (mStateArray.size() > 0) { 1563 f.mSavedViewState = mStateArray; 1564 mStateArray = null; 1565 } 1566 } 1567 1568 Bundle saveFragmentBasicState(Fragment f) { 1569 Bundle result = null; 1570 1571 if (mStateBundle == null) { 1572 mStateBundle = new Bundle(); 1573 } 1574 f.onSaveInstanceState(mStateBundle); 1575 if (!mStateBundle.isEmpty()) { 1576 result = mStateBundle; 1577 mStateBundle = null; 1578 } 1579 1580 if (f.mView != null) { 1581 saveFragmentViewState(f); 1582 } 1583 if (f.mSavedViewState != null) { 1584 if (result == null) { 1585 result = new Bundle(); 1586 } 1587 result.putSparseParcelableArray( 1588 FragmentManagerImpl.VIEW_STATE_TAG, f.mSavedViewState); 1589 } 1590 if (!f.mUserVisibleHint) { 1591 if (result == null) { 1592 result = new Bundle(); 1593 } 1594 // Only add this if it's not the default value 1595 result.putBoolean(FragmentManagerImpl.USER_VISIBLE_HINT_TAG, f.mUserVisibleHint); 1596 } 1597 1598 return result; 1599 } 1600 1601 Parcelable saveAllState() { 1602 // Make sure all pending operations have now been executed to get 1603 // our state update-to-date. 1604 execPendingActions(); 1605 1606 if (HONEYCOMB) { 1607 // As of Honeycomb, we save state after pausing. Prior to that 1608 // it is before pausing. With fragments this is an issue, since 1609 // there are many things you may do after pausing but before 1610 // stopping that change the fragment state. For those older 1611 // devices, we will not at this point say that we have saved 1612 // the state, so we will allow them to continue doing fragment 1613 // transactions. This retains the same semantics as Honeycomb, 1614 // though you do have the risk of losing the very most recent state 1615 // if the process is killed... we'll live with that. 1616 mStateSaved = true; 1617 } 1618 1619 if (mActive == null || mActive.size() <= 0) { 1620 return null; 1621 } 1622 1623 // First collect all active fragments. 1624 int N = mActive.size(); 1625 FragmentState[] active = new FragmentState[N]; 1626 boolean haveFragments = false; 1627 for (int i=0; i<N; i++) { 1628 Fragment f = mActive.get(i); 1629 if (f != null) { 1630 if (f.mIndex < 0) { 1631 String msg = "Failure saving state: active " + f 1632 + " has cleared index: " + f.mIndex; 1633 Log.e(TAG, msg); 1634 dump(" ", null, new PrintWriter(new LogWriter(TAG)), new String[] { }); 1635 throw new IllegalStateException(msg); 1636 } 1637 1638 haveFragments = true; 1639 1640 FragmentState fs = new FragmentState(f); 1641 active[i] = fs; 1642 1643 if (f.mState > Fragment.INITIALIZING && fs.mSavedFragmentState == null) { 1644 fs.mSavedFragmentState = saveFragmentBasicState(f); 1645 1646 if (f.mTarget != null) { 1647 if (f.mTarget.mIndex < 0) { 1648 String msg = "Failure saving state: " + f 1649 + " has target not in fragment manager: " + f.mTarget; 1650 Log.e(TAG, msg); 1651 dump(" ", null, new PrintWriter(new LogWriter(TAG)), new String[] { }); 1652 throw new IllegalStateException(msg); 1653 } 1654 if (fs.mSavedFragmentState == null) { 1655 fs.mSavedFragmentState = new Bundle(); 1656 } 1657 putFragment(fs.mSavedFragmentState, 1658 FragmentManagerImpl.TARGET_STATE_TAG, f.mTarget); 1659 if (f.mTargetRequestCode != 0) { 1660 fs.mSavedFragmentState.putInt( 1661 FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 1662 f.mTargetRequestCode); 1663 } 1664 } 1665 1666 } else { 1667 fs.mSavedFragmentState = f.mSavedFragmentState; 1668 } 1669 1670 if (DEBUG) Log.v(TAG, "Saved state of " + f + ": " 1671 + fs.mSavedFragmentState); 1672 } 1673 } 1674 1675 if (!haveFragments) { 1676 if (DEBUG) Log.v(TAG, "saveAllState: no fragments!"); 1677 return null; 1678 } 1679 1680 int[] added = null; 1681 BackStackState[] backStack = null; 1682 1683 // Build list of currently added fragments. 1684 if (mAdded != null) { 1685 N = mAdded.size(); 1686 if (N > 0) { 1687 added = new int[N]; 1688 for (int i=0; i<N; i++) { 1689 added[i] = mAdded.get(i).mIndex; 1690 if (added[i] < 0) { 1691 String msg = "Failure saving state: active " + mAdded.get(i) 1692 + " has cleared index: " + added[i]; 1693 Log.e(TAG, msg); 1694 dump(" ", null, new PrintWriter(new LogWriter(TAG)), new String[] { }); 1695 throw new IllegalStateException(msg); 1696 } 1697 if (DEBUG) Log.v(TAG, "saveAllState: adding fragment #" + i 1698 + ": " + mAdded.get(i)); 1699 } 1700 } 1701 } 1702 1703 // Now save back stack. 1704 if (mBackStack != null) { 1705 N = mBackStack.size(); 1706 if (N > 0) { 1707 backStack = new BackStackState[N]; 1708 for (int i=0; i<N; i++) { 1709 backStack[i] = new BackStackState(this, mBackStack.get(i)); 1710 if (DEBUG) Log.v(TAG, "saveAllState: adding back stack #" + i 1711 + ": " + mBackStack.get(i)); 1712 } 1713 } 1714 } 1715 1716 FragmentManagerState fms = new FragmentManagerState(); 1717 fms.mActive = active; 1718 fms.mAdded = added; 1719 fms.mBackStack = backStack; 1720 return fms; 1721 } 1722 1723 void restoreAllState(Parcelable state, ArrayList<Fragment> nonConfig) { 1724 // If there is no saved state at all, then there can not be 1725 // any nonConfig fragments either, so that is that. 1726 if (state == null) return; 1727 FragmentManagerState fms = (FragmentManagerState)state; 1728 if (fms.mActive == null) return; 1729 1730 // First re-attach any non-config instances we are retaining back 1731 // to their saved state, so we don't try to instantiate them again. 1732 if (nonConfig != null) { 1733 for (int i=0; i<nonConfig.size(); i++) { 1734 Fragment f = nonConfig.get(i); 1735 if (DEBUG) Log.v(TAG, "restoreAllState: re-attaching retained " + f); 1736 FragmentState fs = fms.mActive[f.mIndex]; 1737 fs.mInstance = f; 1738 f.mSavedViewState = null; 1739 f.mBackStackNesting = 0; 1740 f.mInLayout = false; 1741 f.mAdded = false; 1742 f.mTarget = null; 1743 if (fs.mSavedFragmentState != null) { 1744 fs.mSavedFragmentState.setClassLoader(mActivity.getClassLoader()); 1745 f.mSavedViewState = fs.mSavedFragmentState.getSparseParcelableArray( 1746 FragmentManagerImpl.VIEW_STATE_TAG); 1747 } 1748 } 1749 } 1750 1751 // Build the full list of active fragments, instantiating them from 1752 // their saved state. 1753 mActive = new ArrayList<Fragment>(fms.mActive.length); 1754 if (mAvailIndices != null) { 1755 mAvailIndices.clear(); 1756 } 1757 for (int i=0; i<fms.mActive.length; i++) { 1758 FragmentState fs = fms.mActive[i]; 1759 if (fs != null) { 1760 Fragment f = fs.instantiate(mActivity); 1761 if (DEBUG) Log.v(TAG, "restoreAllState: adding #" + i + ": " + f); 1762 mActive.add(f); 1763 // Now that the fragment is instantiated (or came from being 1764 // retained above), clear mInstance in case we end up re-restoring 1765 // from this FragmentState again. 1766 fs.mInstance = null; 1767 } else { 1768 if (DEBUG) Log.v(TAG, "restoreAllState: adding #" + i + ": (null)"); 1769 mActive.add(null); 1770 if (mAvailIndices == null) { 1771 mAvailIndices = new ArrayList<Integer>(); 1772 } 1773 if (DEBUG) Log.v(TAG, "restoreAllState: adding avail #" + i); 1774 mAvailIndices.add(i); 1775 } 1776 } 1777 1778 // Update the target of all retained fragments. 1779 if (nonConfig != null) { 1780 for (int i=0; i<nonConfig.size(); i++) { 1781 Fragment f = nonConfig.get(i); 1782 if (f.mTargetIndex >= 0) { 1783 if (f.mTargetIndex < mActive.size()) { 1784 f.mTarget = mActive.get(f.mTargetIndex); 1785 } else { 1786 Log.w(TAG, "Re-attaching retained fragment " + f 1787 + " target no longer exists: " + f.mTargetIndex); 1788 f.mTarget = null; 1789 } 1790 } 1791 } 1792 } 1793 1794 // Build the list of currently added fragments. 1795 if (fms.mAdded != null) { 1796 mAdded = new ArrayList<Fragment>(fms.mAdded.length); 1797 for (int i=0; i<fms.mAdded.length; i++) { 1798 Fragment f = mActive.get(fms.mAdded[i]); 1799 if (f == null) { 1800 throw new IllegalStateException( 1801 "No instantiated fragment for index #" + fms.mAdded[i]); 1802 } 1803 f.mAdded = true; 1804 if (DEBUG) Log.v(TAG, "restoreAllState: making added #" + i + ": " + f); 1805 mAdded.add(f); 1806 } 1807 } else { 1808 mAdded = null; 1809 } 1810 1811 // Build the back stack. 1812 if (fms.mBackStack != null) { 1813 mBackStack = new ArrayList<BackStackRecord>(fms.mBackStack.length); 1814 for (int i=0; i<fms.mBackStack.length; i++) { 1815 BackStackRecord bse = fms.mBackStack[i].instantiate(this); 1816 if (DEBUG) Log.v(TAG, "restoreAllState: adding bse #" + i 1817 + " (index " + bse.mIndex + "): " + bse); 1818 mBackStack.add(bse); 1819 if (bse.mIndex >= 0) { 1820 setBackStackIndex(bse.mIndex, bse); 1821 } 1822 } 1823 } else { 1824 mBackStack = null; 1825 } 1826 } 1827 1828 public void attachActivity(FragmentActivity activity) { 1829 if (mActivity != null) throw new IllegalStateException(); 1830 mActivity = activity; 1831 } 1832 1833 public void noteStateNotSaved() { 1834 mStateSaved = false; 1835 } 1836 1837 public void dispatchCreate() { 1838 mStateSaved = false; 1839 moveToState(Fragment.CREATED, false); 1840 } 1841 1842 public void dispatchActivityCreated() { 1843 mStateSaved = false; 1844 moveToState(Fragment.ACTIVITY_CREATED, false); 1845 } 1846 1847 public void dispatchStart() { 1848 mStateSaved = false; 1849 moveToState(Fragment.STARTED, false); 1850 } 1851 1852 public void dispatchResume() { 1853 mStateSaved = false; 1854 moveToState(Fragment.RESUMED, false); 1855 } 1856 1857 public void dispatchPause() { 1858 moveToState(Fragment.STARTED, false); 1859 } 1860 1861 public void dispatchStop() { 1862 // See saveAllState() for the explanation of this. We do this for 1863 // all platform versions, to keep our behavior more consistent between 1864 // them. 1865 mStateSaved = true; 1866 1867 moveToState(Fragment.STOPPED, false); 1868 } 1869 1870 public void dispatchReallyStop() { 1871 moveToState(Fragment.ACTIVITY_CREATED, false); 1872 } 1873 1874 public void dispatchDestroy() { 1875 mDestroyed = true; 1876 execPendingActions(); 1877 moveToState(Fragment.INITIALIZING, false); 1878 mActivity = null; 1879 } 1880 1881 public void dispatchConfigurationChanged(Configuration newConfig) { 1882 if (mAdded != null) { 1883 for (int i=0; i<mAdded.size(); i++) { 1884 Fragment f = mAdded.get(i); 1885 if (f != null) { 1886 f.onConfigurationChanged(newConfig); 1887 } 1888 } 1889 } 1890 } 1891 1892 public void dispatchLowMemory() { 1893 if (mAdded != null) { 1894 for (int i=0; i<mAdded.size(); i++) { 1895 Fragment f = mAdded.get(i); 1896 if (f != null) { 1897 f.onLowMemory(); 1898 } 1899 } 1900 } 1901 } 1902 1903 public boolean dispatchCreateOptionsMenu(Menu menu, MenuInflater inflater) { 1904 boolean show = false; 1905 ArrayList<Fragment> newMenus = null; 1906 if (mAdded != null) { 1907 for (int i=0; i<mAdded.size(); i++) { 1908 Fragment f = mAdded.get(i); 1909 if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) { 1910 show = true; 1911 f.onCreateOptionsMenu(menu, inflater); 1912 if (newMenus == null) { 1913 newMenus = new ArrayList<Fragment>(); 1914 } 1915 newMenus.add(f); 1916 } 1917 } 1918 } 1919 1920 if (mCreatedMenus != null) { 1921 for (int i=0; i<mCreatedMenus.size(); i++) { 1922 Fragment f = mCreatedMenus.get(i); 1923 if (newMenus == null || !newMenus.contains(f)) { 1924 f.onDestroyOptionsMenu(); 1925 } 1926 } 1927 } 1928 1929 mCreatedMenus = newMenus; 1930 1931 return show; 1932 } 1933 1934 public boolean dispatchPrepareOptionsMenu(Menu menu) { 1935 boolean show = false; 1936 if (mAdded != null) { 1937 for (int i=0; i<mAdded.size(); i++) { 1938 Fragment f = mAdded.get(i); 1939 if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) { 1940 show = true; 1941 f.onPrepareOptionsMenu(menu); 1942 } 1943 } 1944 } 1945 return show; 1946 } 1947 1948 public boolean dispatchOptionsItemSelected(MenuItem item) { 1949 if (mAdded != null) { 1950 for (int i=0; i<mAdded.size(); i++) { 1951 Fragment f = mAdded.get(i); 1952 if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) { 1953 if (f.onOptionsItemSelected(item)) { 1954 return true; 1955 } 1956 } 1957 } 1958 } 1959 return false; 1960 } 1961 1962 public boolean dispatchContextItemSelected(MenuItem item) { 1963 if (mAdded != null) { 1964 for (int i=0; i<mAdded.size(); i++) { 1965 Fragment f = mAdded.get(i); 1966 if (f != null && !f.mHidden && f.mUserVisibleHint) { 1967 if (f.onContextItemSelected(item)) { 1968 return true; 1969 } 1970 } 1971 } 1972 } 1973 return false; 1974 } 1975 1976 public void dispatchOptionsMenuClosed(Menu menu) { 1977 if (mAdded != null) { 1978 for (int i=0; i<mAdded.size(); i++) { 1979 Fragment f = mAdded.get(i); 1980 if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) { 1981 f.onOptionsMenuClosed(menu); 1982 } 1983 } 1984 } 1985 } 1986 1987 public static int reverseTransit(int transit) { 1988 int rev = 0; 1989 switch (transit) { 1990 case FragmentTransaction.TRANSIT_FRAGMENT_OPEN: 1991 rev = FragmentTransaction.TRANSIT_FRAGMENT_CLOSE; 1992 break; 1993 case FragmentTransaction.TRANSIT_FRAGMENT_CLOSE: 1994 rev = FragmentTransaction.TRANSIT_FRAGMENT_OPEN; 1995 break; 1996 case FragmentTransaction.TRANSIT_FRAGMENT_FADE: 1997 rev = FragmentTransaction.TRANSIT_FRAGMENT_FADE; 1998 break; 1999 } 2000 return rev; 2001 2002 } 2003 2004 public static final int ANIM_STYLE_OPEN_ENTER = 1; 2005 public static final int ANIM_STYLE_OPEN_EXIT = 2; 2006 public static final int ANIM_STYLE_CLOSE_ENTER = 3; 2007 public static final int ANIM_STYLE_CLOSE_EXIT = 4; 2008 public static final int ANIM_STYLE_FADE_ENTER = 5; 2009 public static final int ANIM_STYLE_FADE_EXIT = 6; 2010 2011 public static int transitToStyleIndex(int transit, boolean enter) { 2012 int animAttr = -1; 2013 switch (transit) { 2014 case FragmentTransaction.TRANSIT_FRAGMENT_OPEN: 2015 animAttr = enter ? ANIM_STYLE_OPEN_ENTER : ANIM_STYLE_OPEN_EXIT; 2016 break; 2017 case FragmentTransaction.TRANSIT_FRAGMENT_CLOSE: 2018 animAttr = enter ? ANIM_STYLE_CLOSE_ENTER : ANIM_STYLE_CLOSE_EXIT; 2019 break; 2020 case FragmentTransaction.TRANSIT_FRAGMENT_FADE: 2021 animAttr = enter ? ANIM_STYLE_FADE_ENTER : ANIM_STYLE_FADE_EXIT; 2022 break; 2023 } 2024 return animAttr; 2025 } 2026} 2027