FragmentManager.java revision 990e6fc0326f5948736650c0cb71b6002d443c9c
1cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn/* 2cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Copyright (C) 2011 The Android Open Source Project 3cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * 4cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 5cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * you may not use this file except in compliance with the License. 6cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * You may obtain a copy of the License at 7cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * 8cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 9cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * 10cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 11cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 12cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * See the License for the specific language governing permissions and 14cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * limitations under the License. 15cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 16cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 17cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornpackage android.support.v4.app; 18cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 19990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport static android.support.annotation.RestrictTo.Scope.GROUP_ID; 20990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 219277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackbornimport android.content.Context; 22cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.content.res.Configuration; 2336bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powellimport android.content.res.Resources.NotFoundException; 240f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powellimport android.content.res.TypedArray; 255e63ab9505a3a4d11374cbbec418c1aba921409dChris Banesimport android.os.Build; 26cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.os.Bundle; 27cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.os.Looper; 28cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.os.Parcel; 29cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.os.Parcelable; 3003526560f132021f8fd7290259762ab362d4d567Doris Liuimport android.support.annotation.CallSuper; 31a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbyeimport android.support.annotation.IdRes; 32c39d9c75590eca86a5e7e32a8824ba04a0d42e9bAlan Viveretteimport android.support.annotation.RestrictTo; 33a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbyeimport android.support.annotation.StringRes; 341802bf381380809e224c72008a400715e2e375b4Adam Powellimport android.support.v4.os.BuildCompat; 35cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.support.v4.util.DebugUtils; 36cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.support.v4.util.LogWriter; 37bf0947be2ead9b3d8e5865bcd3d3652d02a2aa5aChris Banesimport android.support.v4.view.LayoutInflaterFactory; 385e63ab9505a3a4d11374cbbec418c1aba921409dChris Banesimport android.support.v4.view.ViewCompat; 390f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powellimport android.util.AttributeSet; 40cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.util.Log; 41cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.util.SparseArray; 42990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.view.Menu; 43990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.view.MenuInflater; 44990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.view.MenuItem; 45990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.view.View; 46990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.view.ViewGroup; 479277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackbornimport android.view.animation.AccelerateInterpolator; 489277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackbornimport android.view.animation.AlphaAnimation; 49cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.view.animation.Animation; 50990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.view.animation.Animation.AnimationListener; 519277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackbornimport android.view.animation.AnimationSet; 52cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.view.animation.AnimationUtils; 539277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackbornimport android.view.animation.DecelerateInterpolator; 549277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackbornimport android.view.animation.Interpolator; 559277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackbornimport android.view.animation.ScaleAnimation; 56cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 57cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport java.io.FileDescriptor; 58cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport java.io.PrintWriter; 59d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liuimport java.lang.reflect.Field; 60cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport java.util.ArrayList; 61cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport java.util.Arrays; 623a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brownimport java.util.List; 63cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 64cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn/** 65cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Static library support version of the framework's {@link android.app.FragmentManager}. 66cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Used to write apps that run on platforms prior to Android 3.0. When running 67cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * on Android 3.0 or above, this implementation is still used; it does not try 689dcd2e58138ca4eb4b18f80b50e8979329e859d6Scott Main * to switch to the framework's implementation. See the framework {@link FragmentManager} 69cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * documentation for a class overview. 709dcd2e58138ca4eb4b18f80b50e8979329e859d6Scott Main * 719dcd2e58138ca4eb4b18f80b50e8979329e859d6Scott Main * <p>Your activity must derive from {@link FragmentActivity} to use this. From such an activity, 729dcd2e58138ca4eb4b18f80b50e8979329e859d6Scott Main * you can acquire the {@link FragmentManager} by calling 739dcd2e58138ca4eb4b18f80b50e8979329e859d6Scott Main * {@link FragmentActivity#getSupportFragmentManager}. 74cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 75cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornpublic abstract class FragmentManager { 76cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 77cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Representation of an entry on the fragment back stack, as created 78cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * with {@link FragmentTransaction#addToBackStack(String) 79cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * FragmentTransaction.addToBackStack()}. Entries can later be 80cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * retrieved with {@link FragmentManager#getBackStackEntryAt(int) 81fd28b81e0501d11989a8ad095c1a54619000df19Aurimas Liutikas * FragmentManager.getBackStackEntryAt()}. 82cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * 83cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * <p>Note that you should never hold on to a BackStackEntry object; 84cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * the identifier as returned by {@link #getId} is the only thing that 85cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * will be persisted across activity instances. 86cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 87cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public interface BackStackEntry { 88cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 89cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Return the unique identifier for the entry. This is the only 90cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * representation of the entry that will persist across activity 91cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * instances. 92cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 93cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public int getId(); 94cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 95cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 962a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn * Get the name that was supplied to 972a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn * {@link FragmentTransaction#addToBackStack(String) 982a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn * FragmentTransaction.addToBackStack(String)} when creating this entry. 992a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn */ 1002a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn public String getName(); 1012a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn 1022a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn /** 103cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Return the full bread crumb title resource identifier for the entry, 104cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * or 0 if it does not have one. 105cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 106a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye @StringRes 107cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public int getBreadCrumbTitleRes(); 108cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 109cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 110cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Return the short bread crumb title resource identifier for the entry, 111cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * or 0 if it does not have one. 112cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 113a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye @StringRes 114cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public int getBreadCrumbShortTitleRes(); 115cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 116cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 117cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Return the full bread crumb title for the entry, or null if it 118cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * does not have one. 119cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 120cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public CharSequence getBreadCrumbTitle(); 121cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 122cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 123cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Return the short bread crumb title for the entry, or null if it 124cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * does not have one. 125cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 126cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public CharSequence getBreadCrumbShortTitle(); 127cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 128cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 129cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 130cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Interface to watch for changes to the back stack. 131cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 132cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public interface OnBackStackChangedListener { 133cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 134cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Called whenever the contents of the back stack change. 135cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 136cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void onBackStackChanged(); 137cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 138cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 139cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 140cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Start a series of edit operations on the Fragments associated with 141cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * this FragmentManager. 142dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas * 143cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * <p>Note: A fragment transaction can only be created/committed prior 144cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * to an activity saving its state. If you try to commit a transaction 145cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * after {@link FragmentActivity#onSaveInstanceState FragmentActivity.onSaveInstanceState()} 146cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * (and prior to a following {@link FragmentActivity#onStart FragmentActivity.onStart} 147cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * or {@link FragmentActivity#onResume FragmentActivity.onResume()}, you will get an error. 148cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * This is because the framework takes care of saving your current fragments 149cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * in the state, and if changes are made after the state is saved then they 150cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * will be lost.</p> 151cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 152cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract FragmentTransaction beginTransaction(); 153cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 154d805095048f6be52cddbd572ee343c4639ba8187Alan Viverette /** 155d805095048f6be52cddbd572ee343c4639ba8187Alan Viverette * @hide -- remove once prebuilts are in. 156d805095048f6be52cddbd572ee343c4639ba8187Alan Viverette * @deprecated 157d805095048f6be52cddbd572ee343c4639ba8187Alan Viverette */ 158c39d9c75590eca86a5e7e32a8824ba04a0d42e9bAlan Viverette @RestrictTo(GROUP_ID) 159cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Deprecated 160cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public FragmentTransaction openTransaction() { 161cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return beginTransaction(); 162cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 163dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 164cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 165cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * After a {@link FragmentTransaction} is committed with 166cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * {@link FragmentTransaction#commit FragmentTransaction.commit()}, it 167cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * is scheduled to be executed asynchronously on the process's main thread. 168cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * If you want to immediately executing any such pending operations, you 169cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * can call this function (only from the main thread) to do so. Note that 170cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * all callbacks and other related behavior will be done from within this 171cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * call, so be careful about where this is called from. 172cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * 1731500716b2257e9f442606fe5bd992ab4e0198dcbAdam Powell * <p>If you are committing a single transaction that does not modify the 1741500716b2257e9f442606fe5bd992ab4e0198dcbAdam Powell * fragment back stack, strongly consider using 1751500716b2257e9f442606fe5bd992ab4e0198dcbAdam Powell * {@link FragmentTransaction#commitNow()} instead. This can help avoid 1761500716b2257e9f442606fe5bd992ab4e0198dcbAdam Powell * unwanted side effects when other code in your app has pending committed 1771500716b2257e9f442606fe5bd992ab4e0198dcbAdam Powell * transactions that expect different timing.</p> 178990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * <p> 179990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * This also forces the start of any postponed Transactions where 180990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@link Fragment#postponeEnterTransition()} has been called. 1811500716b2257e9f442606fe5bd992ab4e0198dcbAdam Powell * 182cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @return Returns true if there were any pending transactions to be 183cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * executed. 184cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 185cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract boolean executePendingTransactions(); 186cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 187cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 188cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Finds a fragment that was identified by the given id either when inflated 189cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * from XML or as the container ID when added in a transaction. This first 190cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * searches through fragments that are currently added to the manager's 191cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * activity; if no such fragment is found, then all fragments currently 192cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * on the back stack associated with this ID are searched. 193cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @return The fragment if found or null otherwise. 194cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 195a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye public abstract Fragment findFragmentById(@IdRes int id); 196cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 197cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 198cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Finds a fragment that was identified by the given tag either when inflated 199cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * from XML or as supplied when added in a transaction. This first 200cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * searches through fragments that are currently added to the manager's 201cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * activity; if no such fragment is found, then all fragments currently 202cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * on the back stack are searched. 203cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @return The fragment if found or null otherwise. 204cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 205cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract Fragment findFragmentByTag(String tag); 206cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 207cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 208cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Flag for {@link #popBackStack(String, int)} 209cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * and {@link #popBackStack(int, int)}: If set, and the name or ID of 210cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * a back stack entry has been supplied, then all matching entries will 211cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * be consumed until one that doesn't match is found or the bottom of 212cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * the stack is reached. Otherwise, all entries up to but not including that entry 213cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * will be removed. 214cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 215cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public static final int POP_BACK_STACK_INCLUSIVE = 1<<0; 216cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 217cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 218cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Pop the top state off the back stack. Returns true if there was one 219cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * to pop, else false. This function is asynchronous -- it enqueues the 220cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * request to pop, but the action will not be performed until the application 221cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * returns to its event loop. 222cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 223cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract void popBackStack(); 224cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 225cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 226cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Like {@link #popBackStack()}, but performs the operation immediately 227cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * inside of the call. This is like calling {@link #executePendingTransactions()} 228990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * afterwards without forcing the start of postponed Transactions. 229cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @return Returns true if there was something popped, else false. 230cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 231cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract boolean popBackStackImmediate(); 232cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 233cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 234cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Pop the last fragment transition from the manager's fragment 235cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * back stack. If there is nothing to pop, false is returned. 236cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * This function is asynchronous -- it enqueues the 237cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * request to pop, but the action will not be performed until the application 238cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * returns to its event loop. 239dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas * 240cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param name If non-null, this is the name of a previous back state 241cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * to look for; if found, all states up to that state will be popped. The 242cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * {@link #POP_BACK_STACK_INCLUSIVE} flag can be used to control whether 243cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * the named state itself is popped. If null, only the top state is popped. 244cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param flags Either 0 or {@link #POP_BACK_STACK_INCLUSIVE}. 245cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 246cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract void popBackStack(String name, int flags); 247cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 248cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 249cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Like {@link #popBackStack(String, int)}, but performs the operation immediately 250cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * inside of the call. This is like calling {@link #executePendingTransactions()} 251990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * afterwards without forcing the start of postponed Transactions. 252cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @return Returns true if there was something popped, else false. 253cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 254cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract boolean popBackStackImmediate(String name, int flags); 255cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 256cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 257cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Pop all back stack states up to the one with the given identifier. 258cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * This function is asynchronous -- it enqueues the 259cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * request to pop, but the action will not be performed until the application 260cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * returns to its event loop. 261dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas * 262cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param id Identifier of the stated to be popped. If no identifier exists, 263cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * false is returned. 264cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * The identifier is the number returned by 265cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * {@link FragmentTransaction#commit() FragmentTransaction.commit()}. The 266cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * {@link #POP_BACK_STACK_INCLUSIVE} flag can be used to control whether 267cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * the named state itself is popped. 268cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param flags Either 0 or {@link #POP_BACK_STACK_INCLUSIVE}. 269cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 270cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract void popBackStack(int id, int flags); 271cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 272cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 273cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Like {@link #popBackStack(int, int)}, but performs the operation immediately 274cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * inside of the call. This is like calling {@link #executePendingTransactions()} 275990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * afterwards without forcing the start of postponed Transactions. 276cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @return Returns true if there was something popped, else false. 277cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 278cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract boolean popBackStackImmediate(int id, int flags); 279cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 280cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 281cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Return the number of entries currently in the back stack. 282cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 283cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract int getBackStackEntryCount(); 284cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 285cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 286cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Return the BackStackEntry at index <var>index</var> in the back stack; 287cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * entries start index 0 being the bottom of the stack. 288cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 289cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract BackStackEntry getBackStackEntryAt(int index); 290cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 291cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 292cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Add a new listener for changes to the fragment back stack. 293cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 294cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract void addOnBackStackChangedListener(OnBackStackChangedListener listener); 295cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 296cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 297cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Remove a listener that was previously added with 298cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * {@link #addOnBackStackChangedListener(OnBackStackChangedListener)}. 299cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 300cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract void removeOnBackStackChangedListener(OnBackStackChangedListener listener); 301cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 302cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 303cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Put a reference to a fragment in a Bundle. This Bundle can be 304cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * persisted as saved state, and when later restoring 305cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * {@link #getFragment(Bundle, String)} will return the current 306cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * instance of the same fragment. 307cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * 308cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param bundle The bundle in which to put the fragment reference. 309cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param key The name of the entry in the bundle. 310cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param fragment The Fragment whose reference is to be stored. 311cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 312cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract void putFragment(Bundle bundle, String key, Fragment fragment); 313cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 314cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 315cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Retrieve the current Fragment instance for a reference previously 316cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * placed with {@link #putFragment(Bundle, String, Fragment)}. 317cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * 318cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param bundle The bundle from which to retrieve the fragment reference. 319cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param key The name of the entry in the bundle. 320cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @return Returns the current Fragment instance that is associated with 321cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * the given reference. 322cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 323cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract Fragment getFragment(Bundle bundle, String key); 324cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 325cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 3263a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown * Get a list of all fragments that have been added to the fragment manager. 3273a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown * 3283a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown * @return The list of all fragments or null if none. 3293a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown * @hide 3303a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown */ 331c39d9c75590eca86a5e7e32a8824ba04a0d42e9bAlan Viverette @RestrictTo(GROUP_ID) 3323a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown public abstract List<Fragment> getFragments(); 3333a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown 3343a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown /** 3355c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * Save the current instance state of the given Fragment. This can be 3365c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * used later when creating a new instance of the Fragment and adding 3375c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * it to the fragment manager, to have it create itself to match the 3385c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * current state returned here. Note that there are limits on how 3395c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * this can be used: 3405c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * 3415c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * <ul> 3425c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * <li>The Fragment must currently be attached to the FragmentManager. 3435c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * <li>A new Fragment created using this saved state must be the same class 3445c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * type as the Fragment it was created from. 3455c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * <li>The saved state can not contain dependencies on other fragments -- 3465c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * that is it can't use {@link #putFragment(Bundle, String, Fragment)} to 3475c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * store a fragment reference because that reference may not be valid when 3485c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * this saved state is later used. Likewise the Fragment's target and 3495c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * result code are not included in this state. 3505c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * </ul> 3515c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * 3525c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * @param f The Fragment whose state is to be saved. 3535c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * @return The generated state. This will be null if there was no 3545c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * interesting state created by the fragment. 3555c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn */ 3565c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn public abstract Fragment.SavedState saveFragmentInstanceState(Fragment f); 3575c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn 3585c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn /** 35901df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler * Returns true if the final {@link android.app.Activity#onDestroy() Activity.onDestroy()} 36001df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler * call has been made on the FragmentManager's Activity, so this instance is now dead. 36101df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler */ 36201df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler public abstract boolean isDestroyed(); 36301df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler 36401df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler /** 365cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Print the FragmentManager's state into the given stream. 366cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * 367cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param prefix Text to print at the front of each line. 368cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param fd The raw file descriptor that the dump is being sent to. 369cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param writer A PrintWriter to which the dump is to be set. 370cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param args Additional arguments to the dump request. 371cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 372cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args); 373cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 374cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 375cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Control whether the framework's internal fragment manager debugging 376cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * logs are turned on. If enabled, you will see output in logcat as 377cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * the framework performs fragment operations. 378cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 379cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public static void enableDebugLogging(boolean enabled) { 380cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentManagerImpl.DEBUG = enabled; 381cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 382cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn} 383cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 384cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornfinal class FragmentManagerState implements Parcelable { 385cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentState[] mActive; 386cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int[] mAdded; 387cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn BackStackState[] mBackStack; 388dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 389cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public FragmentManagerState() { 390cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 391dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 392cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public FragmentManagerState(Parcel in) { 393cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mActive = in.createTypedArray(FragmentState.CREATOR); 394cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAdded = in.createIntArray(); 395cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStack = in.createTypedArray(BackStackState.CREATOR); 396cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 39790ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas 39890ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas @Override 399cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public int describeContents() { 400cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return 0; 401cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 402cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 40390ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas @Override 404cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void writeToParcel(Parcel dest, int flags) { 405cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn dest.writeTypedArray(mActive, flags); 406cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn dest.writeIntArray(mAdded); 407cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn dest.writeTypedArray(mBackStack, flags); 408cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 409dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 410cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public static final Parcelable.Creator<FragmentManagerState> CREATOR 411cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn = new Parcelable.Creator<FragmentManagerState>() { 41290ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas @Override 413cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public FragmentManagerState createFromParcel(Parcel in) { 414cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return new FragmentManagerState(in); 415cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 41690ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas 41790ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas @Override 418cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public FragmentManagerState[] newArray(int size) { 419cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return new FragmentManagerState[size]; 420cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 421cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn }; 422cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn} 423cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 424cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn/** 425cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Container for fragments associated with an activity. 426cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 427bf0947be2ead9b3d8e5865bcd3d3652d02a2aa5aChris Banesfinal class FragmentManagerImpl extends FragmentManager implements LayoutInflaterFactory { 428cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn static boolean DEBUG = false; 429cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn static final String TAG = "FragmentManager"; 430dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 431681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn static final boolean HONEYCOMB = android.os.Build.VERSION.SDK_INT >= 11; 432681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn 433cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn static final String TARGET_REQUEST_CODE_STATE_TAG = "android:target_req_state"; 434cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn static final String TARGET_STATE_TAG = "android:target_state"; 435cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn static final String VIEW_STATE_TAG = "android:view_state"; 43679398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell static final String USER_VISIBLE_HINT_TAG = "android:user_visible_hint"; 437cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 43803526560f132021f8fd7290259762ab362d4d567Doris Liu static class AnimateOnHWLayerIfNeededListener implements AnimationListener { 439c9a859537b0871f84afeeb706a5b425fe3f2b4ddAurimas Liutikas private AnimationListener mOriginalListener; 4401802bf381380809e224c72008a400715e2e375b4Adam Powell private boolean mShouldRunOnHWLayer; 441dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas View mView; 4421802bf381380809e224c72008a400715e2e375b4Adam Powell 44303526560f132021f8fd7290259762ab362d4d567Doris Liu public AnimateOnHWLayerIfNeededListener(final View v, Animation anim) { 44403526560f132021f8fd7290259762ab362d4d567Doris Liu if (v == null || anim == null) { 44503526560f132021f8fd7290259762ab362d4d567Doris Liu return; 44603526560f132021f8fd7290259762ab362d4d567Doris Liu } 44703526560f132021f8fd7290259762ab362d4d567Doris Liu mView = v; 44803526560f132021f8fd7290259762ab362d4d567Doris Liu } 44903526560f132021f8fd7290259762ab362d4d567Doris Liu 450d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu public AnimateOnHWLayerIfNeededListener(final View v, Animation anim, 451d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu AnimationListener listener) { 452d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu if (v == null || anim == null) { 453d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu return; 454d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu } 455c9a859537b0871f84afeeb706a5b425fe3f2b4ddAurimas Liutikas mOriginalListener = listener; 456d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu mView = v; 4571802bf381380809e224c72008a400715e2e375b4Adam Powell mShouldRunOnHWLayer = true; 458d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu } 459d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu 46003526560f132021f8fd7290259762ab362d4d567Doris Liu @Override 46103526560f132021f8fd7290259762ab362d4d567Doris Liu @CallSuper 46203526560f132021f8fd7290259762ab362d4d567Doris Liu public void onAnimationStart(Animation animation) { 463c9a859537b0871f84afeeb706a5b425fe3f2b4ddAurimas Liutikas if (mOriginalListener != null) { 464c9a859537b0871f84afeeb706a5b425fe3f2b4ddAurimas Liutikas mOriginalListener.onAnimationStart(animation); 46503526560f132021f8fd7290259762ab362d4d567Doris Liu } 46603526560f132021f8fd7290259762ab362d4d567Doris Liu } 46703526560f132021f8fd7290259762ab362d4d567Doris Liu 46803526560f132021f8fd7290259762ab362d4d567Doris Liu @Override 46903526560f132021f8fd7290259762ab362d4d567Doris Liu @CallSuper 47003526560f132021f8fd7290259762ab362d4d567Doris Liu public void onAnimationEnd(Animation animation) { 471d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu if (mView != null && mShouldRunOnHWLayer) { 4721802bf381380809e224c72008a400715e2e375b4Adam Powell // If we're attached to a window, assume we're in the normal performTraversals 4731802bf381380809e224c72008a400715e2e375b4Adam Powell // drawing path for Animations running. It's not safe to change the layer type 4741802bf381380809e224c72008a400715e2e375b4Adam Powell // during drawing, so post it to the View to run later. If we're not attached 4751802bf381380809e224c72008a400715e2e375b4Adam Powell // or we're running on N and above, post it to the view. If we're not on N and 4761802bf381380809e224c72008a400715e2e375b4Adam Powell // not attached, do it right now since existing platform versions don't run the 4771802bf381380809e224c72008a400715e2e375b4Adam Powell // hwui renderer for detached views off the UI thread making changing layer type 4781802bf381380809e224c72008a400715e2e375b4Adam Powell // safe, but posting may not be. 4791802bf381380809e224c72008a400715e2e375b4Adam Powell // Prior to N posting to a detached view from a non-Looper thread could cause 4801802bf381380809e224c72008a400715e2e375b4Adam Powell // leaks, since the thread-local run queue on a non-Looper thread would never 4811802bf381380809e224c72008a400715e2e375b4Adam Powell // be flushed. 4821802bf381380809e224c72008a400715e2e375b4Adam Powell if (ViewCompat.isAttachedToWindow(mView) || BuildCompat.isAtLeastN()) { 4831802bf381380809e224c72008a400715e2e375b4Adam Powell mView.post(new Runnable() { 4841802bf381380809e224c72008a400715e2e375b4Adam Powell @Override 4851802bf381380809e224c72008a400715e2e375b4Adam Powell public void run() { 4861802bf381380809e224c72008a400715e2e375b4Adam Powell ViewCompat.setLayerType(mView, ViewCompat.LAYER_TYPE_NONE, null); 4871802bf381380809e224c72008a400715e2e375b4Adam Powell } 4881802bf381380809e224c72008a400715e2e375b4Adam Powell }); 4891802bf381380809e224c72008a400715e2e375b4Adam Powell } else { 4901802bf381380809e224c72008a400715e2e375b4Adam Powell ViewCompat.setLayerType(mView, ViewCompat.LAYER_TYPE_NONE, null); 4911802bf381380809e224c72008a400715e2e375b4Adam Powell } 49203526560f132021f8fd7290259762ab362d4d567Doris Liu } 493c9a859537b0871f84afeeb706a5b425fe3f2b4ddAurimas Liutikas if (mOriginalListener != null) { 494c9a859537b0871f84afeeb706a5b425fe3f2b4ddAurimas Liutikas mOriginalListener.onAnimationEnd(animation); 495d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu } 49603526560f132021f8fd7290259762ab362d4d567Doris Liu } 49703526560f132021f8fd7290259762ab362d4d567Doris Liu 49803526560f132021f8fd7290259762ab362d4d567Doris Liu @Override 49903526560f132021f8fd7290259762ab362d4d567Doris Liu public void onAnimationRepeat(Animation animation) { 500c9a859537b0871f84afeeb706a5b425fe3f2b4ddAurimas Liutikas if (mOriginalListener != null) { 501c9a859537b0871f84afeeb706a5b425fe3f2b4ddAurimas Liutikas mOriginalListener.onAnimationRepeat(animation); 502d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu } 50303526560f132021f8fd7290259762ab362d4d567Doris Liu } 50403526560f132021f8fd7290259762ab362d4d567Doris Liu } 50503526560f132021f8fd7290259762ab362d4d567Doris Liu 506990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<OpGenerator> mPendingActions; 507cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Runnable[] mTmpActions; 508cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn boolean mExecutingActions; 509dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 510cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ArrayList<Fragment> mActive; 511cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ArrayList<Fragment> mAdded; 512cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ArrayList<Integer> mAvailIndices; 513cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ArrayList<BackStackRecord> mBackStack; 514cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ArrayList<Fragment> mCreatedMenus; 515dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 516cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Must be accessed while locked. 517cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ArrayList<BackStackRecord> mBackStackIndices; 518cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ArrayList<Integer> mAvailBackStackIndices; 519cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 520cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ArrayList<OnBackStackChangedListener> mBackStackChangeListeners; 521cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 522cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int mCurState = Fragment.INITIALIZING; 5238491eb62f621cd5de4b4caed839be09c77011f53Todd Kennedy FragmentHostCallback mHost; 524d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy FragmentController mController; 5250adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn FragmentContainer mContainer; 5260adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn Fragment mParent; 527d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu 528d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu static Field sAnimationListenerField = null; 529dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 530cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn boolean mNeedMenuInvalidate; 531cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn boolean mStateSaved; 532cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn boolean mDestroyed; 533cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn String mNoTransactionsBecause; 53479398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell boolean mHavePendingDeferredStart; 535dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 536990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Temporary vars for optimizing execution of BackStackRecords: 537990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<BackStackRecord> mTmpRecords; 538990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Boolean> mTmpIsPop; 539990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Fragment> mTmpAddedFragments; 540990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 541cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Temporary vars for state save and restore. 542cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Bundle mStateBundle = null; 543cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn SparseArray<Parcelable> mStateArray = null; 544dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 545990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Postponed transactions. 546990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<StartEnterTransitionListener> mPostponedTransactions; 547990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 548cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Runnable mExecCommit = new Runnable() { 549cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 550cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void run() { 551cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn execPendingActions(); 552cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 553cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn }; 554cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 55503526560f132021f8fd7290259762ab362d4d567Doris Liu static boolean modifiesAlpha(Animation anim) { 55603526560f132021f8fd7290259762ab362d4d567Doris Liu if (anim instanceof AlphaAnimation) { 55703526560f132021f8fd7290259762ab362d4d567Doris Liu return true; 55803526560f132021f8fd7290259762ab362d4d567Doris Liu } else if (anim instanceof AnimationSet) { 55903526560f132021f8fd7290259762ab362d4d567Doris Liu List<Animation> anims = ((AnimationSet) anim).getAnimations(); 56003526560f132021f8fd7290259762ab362d4d567Doris Liu for (int i = 0; i < anims.size(); i++) { 56103526560f132021f8fd7290259762ab362d4d567Doris Liu if (anims.get(i) instanceof AlphaAnimation) { 56203526560f132021f8fd7290259762ab362d4d567Doris Liu return true; 56303526560f132021f8fd7290259762ab362d4d567Doris Liu } 56403526560f132021f8fd7290259762ab362d4d567Doris Liu } 56503526560f132021f8fd7290259762ab362d4d567Doris Liu } 56603526560f132021f8fd7290259762ab362d4d567Doris Liu return false; 56703526560f132021f8fd7290259762ab362d4d567Doris Liu } 56803526560f132021f8fd7290259762ab362d4d567Doris Liu 56903526560f132021f8fd7290259762ab362d4d567Doris Liu static boolean shouldRunOnHWLayer(View v, Animation anim) { 570b8d65fef161c7cd4bb06dc97685cf3fb3d6c3e1aChris Banes return Build.VERSION.SDK_INT >= 19 571410d77a6fbe42b0784cccd046bb8958caa723035Chris Banes && ViewCompat.getLayerType(v) == ViewCompat.LAYER_TYPE_NONE 57203526560f132021f8fd7290259762ab362d4d567Doris Liu && ViewCompat.hasOverlappingRendering(v) 57303526560f132021f8fd7290259762ab362d4d567Doris Liu && modifiesAlpha(anim); 57403526560f132021f8fd7290259762ab362d4d567Doris Liu } 57503526560f132021f8fd7290259762ab362d4d567Doris Liu 57613fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn private void throwException(RuntimeException ex) { 57713fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn Log.e(TAG, ex.getMessage()); 578ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn Log.e(TAG, "Activity state:"); 57913fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn LogWriter logw = new LogWriter(TAG); 58013fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn PrintWriter pw = new PrintWriter(logw); 581d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy if (mHost != null) { 582ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn try { 5838491eb62f621cd5de4b4caed839be09c77011f53Todd Kennedy mHost.onDump(" ", null, pw, new String[] { }); 584ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn } catch (Exception e) { 585ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn Log.e(TAG, "Failed dumping state", e); 586ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn } 587ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn } else { 588ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn try { 58913fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn dump(" ", null, pw, new String[] { }); 590ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn } catch (Exception e) { 59113fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn Log.e(TAG, "Failed dumping state", e); 592ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn } 593ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn } 59413fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn throw ex; 595ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn } 596ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn 597cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 598cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public FragmentTransaction beginTransaction() { 599cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return new BackStackRecord(this); 600cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 601cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 602cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 603cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean executePendingTransactions() { 604990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean updates = execPendingActions(); 605990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount forcePostponedTransactions(); 606990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return updates; 607cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 608cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 609cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 610cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void popBackStack() { 611990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount enqueueAction(new PopBackStackState(null, -1, 0), false); 612cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 613cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 614cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 615cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean popBackStackImmediate() { 616cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn checkStateLoss(); 617990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return popBackStackImmediate(null, -1, 0); 618cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 619cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 620cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 621cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void popBackStack(final String name, final int flags) { 622990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount enqueueAction(new PopBackStackState(name, -1, flags), false); 623cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 624cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 625cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 626cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean popBackStackImmediate(String name, int flags) { 627cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn checkStateLoss(); 628990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return popBackStackImmediate(name, -1, flags); 629cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 630cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 631cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 632cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void popBackStack(final int id, final int flags) { 633cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (id < 0) { 634cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn throw new IllegalArgumentException("Bad id: " + id); 635cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 636990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount enqueueAction(new PopBackStackState(null, id, flags), false); 637cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 638cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 639cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 640cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean popBackStackImmediate(int id, int flags) { 641cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn checkStateLoss(); 642990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount execPendingActions(); 643cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (id < 0) { 644cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn throw new IllegalArgumentException("Bad id: " + id); 645cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 646990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return popBackStackImmediate(null, id, flags); 647990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 648990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 649990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 650990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Used by all public popBackStackImmediate methods, this executes pending transactions and 651990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * returns true if the pop action did anything, regardless of what other pending 652990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * transactions did. 653990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 654990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @return true if the pop operation did anything or false otherwise. 655990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 656990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private boolean popBackStackImmediate(String name, int id, int flags) { 657990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount execPendingActions(); 658990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ensureExecReady(true); 659990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 660990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean executePop = popBackStackState(mTmpRecords, mTmpIsPop, name, id, flags); 661990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (executePop) { 662990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mExecutingActions = true; 663990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount try { 664990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount optimizeAndExecuteOps(mTmpRecords, mTmpIsPop); 665990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } finally { 666990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount cleanupExec(); 667990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 668990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 669990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 670990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount doPendingDeferredStart(); 671990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return executePop; 672cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 673cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 674cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 675cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public int getBackStackEntryCount() { 676cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return mBackStack != null ? mBackStack.size() : 0; 677cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 678cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 679cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 680cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public BackStackEntry getBackStackEntryAt(int index) { 681cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return mBackStack.get(index); 682cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 683cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 684cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 685cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void addOnBackStackChangedListener(OnBackStackChangedListener listener) { 686cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStackChangeListeners == null) { 687cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackChangeListeners = new ArrayList<OnBackStackChangedListener>(); 688cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 689cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackChangeListeners.add(listener); 690cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 691cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 692cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 693cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void removeOnBackStackChangedListener(OnBackStackChangedListener listener) { 694cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStackChangeListeners != null) { 695cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackChangeListeners.remove(listener); 696cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 697cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 698cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 699cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 700cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void putFragment(Bundle bundle, String key, Fragment fragment) { 701cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (fragment.mIndex < 0) { 70213fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn throwException(new IllegalStateException("Fragment " + fragment 70313fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn + " is not currently in the FragmentManager")); 704cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 705cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn bundle.putInt(key, fragment.mIndex); 706cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 707cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 708cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 709cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public Fragment getFragment(Bundle bundle, String key) { 710cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int index = bundle.getInt(key, -1); 711cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (index == -1) { 712cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 713cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 714cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (index >= mActive.size()) { 7152b336307cf98ca5142db6736812178293d47c500Cyril Mottier throwException(new IllegalStateException("Fragment no longer exists for key " 71613fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn + key + ": index " + index)); 717cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 718cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mActive.get(index); 719cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f == null) { 7202b336307cf98ca5142db6736812178293d47c500Cyril Mottier throwException(new IllegalStateException("Fragment no longer exists for key " 72113fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn + key + ": index " + index)); 722cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 723cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return f; 724cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 725cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 726cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 7273a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown public List<Fragment> getFragments() { 7283a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown return mActive; 7293a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown } 7303a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown 7313a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown @Override 7325c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn public Fragment.SavedState saveFragmentInstanceState(Fragment fragment) { 7335c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn if (fragment.mIndex < 0) { 73413fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn throwException( new IllegalStateException("Fragment " + fragment 73513fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn + " is not currently in the FragmentManager")); 7365c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 7375c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn if (fragment.mState > Fragment.INITIALIZING) { 7385c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn Bundle result = saveFragmentBasicState(fragment); 7395c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn return result != null ? new Fragment.SavedState(result) : null; 7405c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 7415c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn return null; 7425c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 7435c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn 7445c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn @Override 74501df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler public boolean isDestroyed() { 74601df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler return mDestroyed; 74701df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler } 74801df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler 74901df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler @Override 750cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public String toString() { 751cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn StringBuilder sb = new StringBuilder(128); 752cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn sb.append("FragmentManager{"); 753cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn sb.append(Integer.toHexString(System.identityHashCode(this))); 754cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn sb.append(" in "); 7550adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (mParent != null) { 7560adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn DebugUtils.buildShortClassTag(mParent, sb); 7570adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn } else { 758d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy DebugUtils.buildShortClassTag(mHost, sb); 7590adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn } 760cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn sb.append("}}"); 761cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return sb.toString(); 762cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 763cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 764cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 765cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { 766cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn String innerPrefix = prefix + " "; 767cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 768cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int N; 769cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mActive != null) { 770cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn N = mActive.size(); 771cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (N > 0) { 772cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print("Active Fragments in "); 773cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(Integer.toHexString(System.identityHashCode(this))); 774cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.println(":"); 775cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<N; i++) { 776cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mActive.get(i); 777cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" #"); writer.print(i); 778cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(": "); writer.println(f); 779cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f != null) { 780cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.dump(innerPrefix, fd, writer, args); 781cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 782cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 783cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 784cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 785cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 786cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mAdded != null) { 787cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn N = mAdded.size(); 788cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (N > 0) { 789cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.println("Added Fragments:"); 790cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<N; i++) { 791cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mAdded.get(i); 792cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" #"); writer.print(i); 793cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(": "); writer.println(f.toString()); 794cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 795cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 796cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 797cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 798cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mCreatedMenus != null) { 799cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn N = mCreatedMenus.size(); 800cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (N > 0) { 801cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.println("Fragments Created Menus:"); 802cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<N; i++) { 803cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mCreatedMenus.get(i); 804cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" #"); writer.print(i); 805cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(": "); writer.println(f.toString()); 806cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 807cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 808cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 809cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 810cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStack != null) { 811cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn N = mBackStack.size(); 812cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (N > 0) { 813cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.println("Back Stack:"); 814cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<N; i++) { 815cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn BackStackRecord bs = mBackStack.get(i); 816cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" #"); writer.print(i); 817cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(": "); writer.println(bs.toString()); 818cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn bs.dump(innerPrefix, fd, writer, args); 819cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 820cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 821cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 822cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 823cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn synchronized (this) { 824cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStackIndices != null) { 825cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn N = mBackStackIndices.size(); 826cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (N > 0) { 827cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.println("Back Stack Indices:"); 828cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<N; i++) { 829cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn BackStackRecord bs = mBackStackIndices.get(i); 830cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" #"); writer.print(i); 831cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(": "); writer.println(bs); 832cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 833cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 834cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 835cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 836cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mAvailBackStackIndices != null && mAvailBackStackIndices.size() > 0) { 837cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print("mAvailBackStackIndices: "); 838cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.println(Arrays.toString(mAvailBackStackIndices.toArray())); 839cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 840cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 841cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 842cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mPendingActions != null) { 843cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn N = mPendingActions.size(); 844cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (N > 0) { 845cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.println("Pending Actions:"); 846cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<N; i++) { 847990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount OpGenerator r = mPendingActions.get(i); 848cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" #"); writer.print(i); 849cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(": "); writer.println(r); 850cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 851cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 852cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 853cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 854cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.println("FragmentManager misc state:"); 855d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy writer.print(prefix); writer.print(" mHost="); writer.println(mHost); 8560adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn writer.print(prefix); writer.print(" mContainer="); writer.println(mContainer); 8570adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (mParent != null) { 8580adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn writer.print(prefix); writer.print(" mParent="); writer.println(mParent); 8590adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn } 860cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" mCurState="); writer.print(mCurState); 861cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(" mStateSaved="); writer.print(mStateSaved); 862cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(" mDestroyed="); writer.println(mDestroyed); 863cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mNeedMenuInvalidate) { 864cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" mNeedMenuInvalidate="); 865cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.println(mNeedMenuInvalidate); 866cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 867cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mNoTransactionsBecause != null) { 868cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" mNoTransactionsBecause="); 869cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.println(mNoTransactionsBecause); 870cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 871cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mAvailIndices != null && mAvailIndices.size() > 0) { 872cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" mAvailIndices: "); 873cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.println(Arrays.toString(mAvailIndices.toArray())); 874cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 875cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 876cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 8779277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn static final Interpolator DECELERATE_QUINT = new DecelerateInterpolator(2.5f); 8789277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn static final Interpolator DECELERATE_CUBIC = new DecelerateInterpolator(1.5f); 8799277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn static final Interpolator ACCELERATE_QUINT = new AccelerateInterpolator(2.5f); 8809277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn static final Interpolator ACCELERATE_CUBIC = new AccelerateInterpolator(1.5f); 881dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 8829277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn static final int ANIM_DUR = 220; 883dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 8849277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn static Animation makeOpenCloseAnimation(Context context, float startScale, 8859277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn float endScale, float startAlpha, float endAlpha) { 8869277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn AnimationSet set = new AnimationSet(false); 8879277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn ScaleAnimation scale = new ScaleAnimation(startScale, endScale, startScale, endScale, 8889277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn Animation.RELATIVE_TO_SELF, .5f, Animation.RELATIVE_TO_SELF, .5f); 8899277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn scale.setInterpolator(DECELERATE_QUINT); 8909277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn scale.setDuration(ANIM_DUR); 8919277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn set.addAnimation(scale); 8929277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn AlphaAnimation alpha = new AlphaAnimation(startAlpha, endAlpha); 8939277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn alpha.setInterpolator(DECELERATE_CUBIC); 8949277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn alpha.setDuration(ANIM_DUR); 8959277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn set.addAnimation(alpha); 8969277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn return set; 8979277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn } 898dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 8999277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn static Animation makeFadeAnimation(Context context, float start, float end) { 9009277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn AlphaAnimation anim = new AlphaAnimation(start, end); 9019277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn anim.setInterpolator(DECELERATE_CUBIC); 9029277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn anim.setDuration(ANIM_DUR); 9039277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn return anim; 9049277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn } 90503526560f132021f8fd7290259762ab362d4d567Doris Liu 9069277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn Animation loadAnimation(Fragment fragment, int transit, boolean enter, 907cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int transitionStyle) { 908990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Animation animObj = fragment.onCreateAnimation(transit, enter, fragment.getNextAnim()); 909cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (animObj != null) { 910cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return animObj; 911cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 912dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 913990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (fragment.getNextAnim() != 0) { 914990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Animation anim = AnimationUtils.loadAnimation(mHost.getContext(), 915990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.getNextAnim()); 916cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (anim != null) { 917cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return anim; 918cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 919cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 920dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 921cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (transit == 0) { 922cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 923cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 924dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 925cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int styleIndex = transitToStyleIndex(transit, enter); 926cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (styleIndex < 0) { 927cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 928cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 92903526560f132021f8fd7290259762ab362d4d567Doris Liu 9309277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn switch (styleIndex) { 9319277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn case ANIM_STYLE_OPEN_ENTER: 932d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy return makeOpenCloseAnimation(mHost.getContext(), 1.125f, 1.0f, 0, 1); 9339277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn case ANIM_STYLE_OPEN_EXIT: 934d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy return makeOpenCloseAnimation(mHost.getContext(), 1.0f, .975f, 1, 0); 9359277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn case ANIM_STYLE_CLOSE_ENTER: 936d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy return makeOpenCloseAnimation(mHost.getContext(), .975f, 1.0f, 0, 1); 9379277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn case ANIM_STYLE_CLOSE_EXIT: 938d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy return makeOpenCloseAnimation(mHost.getContext(), 1.0f, 1.075f, 1, 0); 9399277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn case ANIM_STYLE_FADE_ENTER: 940d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy return makeFadeAnimation(mHost.getContext(), 0, 1); 9419277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn case ANIM_STYLE_FADE_EXIT: 942d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy return makeFadeAnimation(mHost.getContext(), 1, 0); 9439277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn } 944dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 9458491eb62f621cd5de4b4caed839be09c77011f53Todd Kennedy if (transitionStyle == 0 && mHost.onHasWindowAnimations()) { 9468491eb62f621cd5de4b4caed839be09c77011f53Todd Kennedy transitionStyle = mHost.onGetWindowAnimations(); 947cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 948cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (transitionStyle == 0) { 949cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 950cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 951dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 952cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn //TypedArray attrs = mActivity.obtainStyledAttributes(transitionStyle, 953cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // com.android.internal.R.styleable.FragmentAnimation); 954cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn //int anim = attrs.getResourceId(styleIndex, 0); 955cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn //attrs.recycle(); 956dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 957cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn //if (anim == 0) { 958cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // return null; 959cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn //} 960dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 961cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn //return AnimatorInflater.loadAnimator(mActivity, anim); 962cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 963cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 964dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 965abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell public void performPendingDeferredStart(Fragment f) { 966abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell if (f.mDeferStart) { 96779398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell if (mExecutingActions) { 96879398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell // Wait until we're done executing our pending transactions 96979398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell mHavePendingDeferredStart = true; 97079398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell return; 97179398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell } 972abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell f.mDeferStart = false; 9735506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn moveToState(f, mCurState, 0, 0, false); 974abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell } 975abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell } 976abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell 97703526560f132021f8fd7290259762ab362d4d567Doris Liu /** 97803526560f132021f8fd7290259762ab362d4d567Doris Liu * Sets the to be animated view on hardware layer during the animation. Note 97903526560f132021f8fd7290259762ab362d4d567Doris Liu * that calling this will replace any existing animation listener on the animation 98003526560f132021f8fd7290259762ab362d4d567Doris Liu * with a new one, as animations do not support more than one listeners. Therefore, 98103526560f132021f8fd7290259762ab362d4d567Doris Liu * animations that already have listeners should do the layer change operations 98203526560f132021f8fd7290259762ab362d4d567Doris Liu * in their existing listeners, rather than calling this function. 98303526560f132021f8fd7290259762ab362d4d567Doris Liu */ 98403526560f132021f8fd7290259762ab362d4d567Doris Liu private void setHWLayerAnimListenerIfAlpha(final View v, Animation anim) { 98503526560f132021f8fd7290259762ab362d4d567Doris Liu if (v == null || anim == null) { 98603526560f132021f8fd7290259762ab362d4d567Doris Liu return; 98703526560f132021f8fd7290259762ab362d4d567Doris Liu } 98803526560f132021f8fd7290259762ab362d4d567Doris Liu if (shouldRunOnHWLayer(v, anim)) { 989d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu AnimationListener originalListener = null; 990d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu try { 991d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu if (sAnimationListenerField == null) { 992d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu sAnimationListenerField = Animation.class.getDeclaredField("mListener"); 993d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu sAnimationListenerField.setAccessible(true); 994d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu } 995d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu originalListener = (AnimationListener) sAnimationListenerField.get(anim); 996d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu } catch (NoSuchFieldException e) { 997d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu Log.e(TAG, "No field with the name mListener is found in Animation class", e); 998d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu } catch (IllegalAccessException e) { 999d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu Log.e(TAG, "Cannot access Animation's mListener field", e); 1000d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu } 1001d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu // If there's already a listener set on the animation, we need wrap the new listener 1002d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu // around the existing listener, so that they will both get animation listener 1003d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu // callbacks. 10041802bf381380809e224c72008a400715e2e375b4Adam Powell ViewCompat.setLayerType(v, ViewCompat.LAYER_TYPE_HARDWARE, null); 1005d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu anim.setAnimationListener(new AnimateOnHWLayerIfNeededListener(v, anim, 1006d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu originalListener)); 100703526560f132021f8fd7290259762ab362d4d567Doris Liu } 100803526560f132021f8fd7290259762ab362d4d567Doris Liu } 100903526560f132021f8fd7290259762ab362d4d567Doris Liu 1010fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell boolean isStateAtLeast(int state) { 1011fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell return mCurState >= state; 1012fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell } 1013fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell 10145506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn void moveToState(Fragment f, int newState, int transit, int transitionStyle, 10155506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn boolean keepActive) { 1016cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Fragments that are not currently added will sit in the onCreate() state. 101774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn if ((!f.mAdded || f.mDetached) && newState > Fragment.CREATED) { 1018cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn newState = Fragment.CREATED; 1019cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 10202c4b5dbfee5232bcbbcb74b84ce9147b62a9d789Dianne Hackborn if (f.mRemoving && newState > f.mState) { 10212c4b5dbfee5232bcbbcb74b84ce9147b62a9d789Dianne Hackborn // While removing a fragment, we can't change it to a higher state. 10222c4b5dbfee5232bcbbcb74b84ce9147b62a9d789Dianne Hackborn newState = f.mState; 10232c4b5dbfee5232bcbbcb74b84ce9147b62a9d789Dianne Hackborn } 10246cafd27a3c89dfed10d7e226dc6168307513d4a6Adam Powell // Defer start if requested; don't allow it to move to STARTED or higher 10256cafd27a3c89dfed10d7e226dc6168307513d4a6Adam Powell // if it's not already started. 10266cafd27a3c89dfed10d7e226dc6168307513d4a6Adam Powell if (f.mDeferStart && f.mState < Fragment.STARTED && newState > Fragment.STOPPED) { 1027abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell newState = Fragment.STOPPED; 1028abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell } 1029cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mState < newState) { 10309277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn // For fragments that are created from a layout, when restoring from 10319277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn // state we don't want to allow them to be created until they are 10329277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn // being reloaded from the layout. 10339277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn if (f.mFromLayout && !f.mInLayout) { 10349277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn return; 1035dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas } 1036990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.getAnimatingAway() != null) { 1037cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // The fragment is currently being animated... but! Now we 1038cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // want to move our state back up. Give up on waiting for the 1039cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // animation, move to whatever the final state should be once 1040cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // the animation is done, and then we can proceed from there. 1041990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.setAnimatingAway(null); 1042990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveToState(f, f.getStateAfterAnimating(), 0, 0, true); 1043cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1044cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn switch (f.mState) { 1045cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case Fragment.INITIALIZING: 1046cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "moveto CREATED: " + f); 1047cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mSavedFragmentState != null) { 1048d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy f.mSavedFragmentState.setClassLoader(mHost.getContext().getClassLoader()); 1049cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray( 1050cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentManagerImpl.VIEW_STATE_TAG); 1051cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mTarget = getFragment(f.mSavedFragmentState, 1052cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentManagerImpl.TARGET_STATE_TAG); 1053cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mTarget != null) { 1054cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mTargetRequestCode = f.mSavedFragmentState.getInt( 1055cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0); 1056cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 105779398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell f.mUserVisibleHint = f.mSavedFragmentState.getBoolean( 105879398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true); 105979398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell if (!f.mUserVisibleHint) { 106079398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell f.mDeferStart = true; 106179398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell if (newState > Fragment.STOPPED) { 106279398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell newState = Fragment.STOPPED; 106379398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell } 106479398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell } 1065cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1066d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy f.mHost = mHost; 10670adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.mParentFragment = mParent; 10680adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.mFragmentManager = mParent != null 1069d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy ? mParent.mChildFragmentManager : mHost.getFragmentManagerImpl(); 1070cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mCalled = false; 1071b979cb86fa389effb7cd79fa045550c10b7b4819Todd Kennedy f.onAttach(mHost.getContext()); 1072cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (!f.mCalled) { 1073cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn throw new SuperNotCalledException("Fragment " + f 1074cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn + " did not call through to super.onAttach()"); 1075cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 10760adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (f.mParentFragment == null) { 1077b979cb86fa389effb7cd79fa045550c10b7b4819Todd Kennedy mHost.onAttachFragment(f); 1078cef09fee2126f901aa164f6e89c370ab81cff1b3Adam Powell } else { 1079cef09fee2126f901aa164f6e89c370ab81cff1b3Adam Powell f.mParentFragment.onAttachFragment(f); 10800adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn } 10810adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn 1082cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (!f.mRetaining) { 10830adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.performCreate(f.mSavedFragmentState); 10849375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell } else { 10859375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell f.restoreChildFragmentState(f.mSavedFragmentState); 10869375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell f.mState = Fragment.CREATED; 1087cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1088cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mRetaining = false; 1089cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mFromLayout) { 1090cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // For fragments that are part of the content view 1091cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // layout, we need to instantiate the view immediately 1092cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // and the inflater will take care of adding it. 10930adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.mView = f.performCreateView(f.getLayoutInflater( 10940adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.mSavedFragmentState), null, f.mSavedFragmentState); 1095cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mView != null) { 1096cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mInnerView = f.mView; 10975e63ab9505a3a4d11374cbbec418c1aba921409dChris Banes if (Build.VERSION.SDK_INT >= 11) { 10985e63ab9505a3a4d11374cbbec418c1aba921409dChris Banes ViewCompat.setSaveFromParentEnabled(f.mView, false); 10995e63ab9505a3a4d11374cbbec418c1aba921409dChris Banes } else { 11005e63ab9505a3a4d11374cbbec418c1aba921409dChris Banes f.mView = NoSaveStateFrameLayout.wrap(f.mView); 11015e63ab9505a3a4d11374cbbec418c1aba921409dChris Banes } 1102715a71e5f73cbc33f307cbd3625db8f889a05c1aDianne Hackborn if (f.mHidden) f.mView.setVisibility(View.GONE); 1103e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn f.onViewCreated(f.mView, f.mSavedFragmentState); 1104cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 1105cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mInnerView = null; 1106cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1107cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1108cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case Fragment.CREATED: 1109cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (newState > Fragment.CREATED) { 1110e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f); 1111cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (!f.mFromLayout) { 1112cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ViewGroup container = null; 1113cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mContainerId != 0) { 111436bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell if (f.mContainerId == View.NO_ID) { 111536bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell throwException(new IllegalArgumentException( 111636bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell "Cannot create fragment " 111736bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell + f 111836bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell + " for a container view with no id")); 111936bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell } 112036bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell container = (ViewGroup) mContainer.onFindViewById(f.mContainerId); 1121cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (container == null && !f.mRestored) { 112236bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell String resName; 112336bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell try { 112436bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell resName = f.getResources().getResourceName(f.mContainerId); 112536bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell } catch (NotFoundException e) { 112636bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell resName = "unknown"; 112736bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell } 112813fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn throwException(new IllegalArgumentException( 112913fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn "No view found for id 0x" 113013fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn + Integer.toHexString(f.mContainerId) + " (" 113136bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell + resName 113213fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn + ") for fragment " + f)); 1133cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1134cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1135cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mContainer = container; 11360adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.mView = f.performCreateView(f.getLayoutInflater( 11370adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.mSavedFragmentState), container, f.mSavedFragmentState); 1138cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mView != null) { 1139cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mInnerView = f.mView; 11405e63ab9505a3a4d11374cbbec418c1aba921409dChris Banes if (Build.VERSION.SDK_INT >= 11) { 11415e63ab9505a3a4d11374cbbec418c1aba921409dChris Banes ViewCompat.setSaveFromParentEnabled(f.mView, false); 11425e63ab9505a3a4d11374cbbec418c1aba921409dChris Banes } else { 11435e63ab9505a3a4d11374cbbec418c1aba921409dChris Banes f.mView = NoSaveStateFrameLayout.wrap(f.mView); 11445e63ab9505a3a4d11374cbbec418c1aba921409dChris Banes } 1145cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (container != null) { 1146cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn container.addView(f.mView); 1147990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.mIsNewlyAdded = true; 1148990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1149990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.mHidden) { 1150990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.mView.setVisibility(View.GONE); 1151990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.mIsNewlyAdded = false; // No animation 1152cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1153e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn f.onViewCreated(f.mView, f.mSavedFragmentState); 1154cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 1155cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mInnerView = null; 1156cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1157cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 11580adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn 11590adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.performActivityCreated(f.mSavedFragmentState); 1160e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (f.mView != null) { 11610adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.restoreViewState(f.mSavedFragmentState); 1162e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1163cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mSavedFragmentState = null; 1164cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1165cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case Fragment.ACTIVITY_CREATED: 11669375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell if (newState > Fragment.ACTIVITY_CREATED) { 11679375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell f.mState = Fragment.STOPPED; 11689375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell } 1169e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn case Fragment.STOPPED: 1170e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (newState > Fragment.STOPPED) { 1171cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "moveto STARTED: " + f); 11729c53b844bd525e6a04e17291efc38713893074cdDianne Hackborn f.performStart(); 1173cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1174cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case Fragment.STARTED: 1175cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (newState > Fragment.STARTED) { 1176cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f); 11770adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.performResume(); 11784e6647fe2551985f33407acd712a4942b090207aDianne Hackborn f.mSavedFragmentState = null; 11794e6647fe2551985f33407acd712a4942b090207aDianne Hackborn f.mSavedViewState = null; 1180cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1181cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1182cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else if (f.mState > newState) { 1183cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn switch (f.mState) { 1184cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case Fragment.RESUMED: 1185cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (newState < Fragment.RESUMED) { 1186cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "movefrom RESUMED: " + f); 11870adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.performPause(); 1188cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1189cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case Fragment.STARTED: 1190cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (newState < Fragment.STARTED) { 1191cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "movefrom STARTED: " + f); 1192cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.performStop(); 1193cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1194e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn case Fragment.STOPPED: 1195218c1e661578e2a17928f7dbb590b43d1c79aeb7Dianne Hackborn if (newState < Fragment.STOPPED) { 1196218c1e661578e2a17928f7dbb590b43d1c79aeb7Dianne Hackborn if (DEBUG) Log.v(TAG, "movefrom STOPPED: " + f); 1197218c1e661578e2a17928f7dbb590b43d1c79aeb7Dianne Hackborn f.performReallyStop(); 1198218c1e661578e2a17928f7dbb590b43d1c79aeb7Dianne Hackborn } 1199cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case Fragment.ACTIVITY_CREATED: 1200cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (newState < Fragment.ACTIVITY_CREATED) { 1201e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (DEBUG) Log.v(TAG, "movefrom ACTIVITY_CREATED: " + f); 1202cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mView != null) { 1203cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Need to save the current view state if not 1204cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // done already. 12058491eb62f621cd5de4b4caed839be09c77011f53Todd Kennedy if (mHost.onShouldSaveFragmentState(f) && f.mSavedViewState == null) { 1206cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn saveFragmentViewState(f); 1207cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1208cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 12099c53b844bd525e6a04e17291efc38713893074cdDianne Hackborn f.performDestroyView(); 1210cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mView != null && f.mContainer != null) { 1211cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Animation anim = null; 1212990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mCurState > Fragment.INITIALIZING && !mDestroyed 1213990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount && f.mView.getVisibility() == View.VISIBLE) { 12149277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn anim = loadAnimation(f, transit, false, 1215cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn transitionStyle); 1216cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1217cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (anim != null) { 1218cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn final Fragment fragment = f; 1219990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.setAnimatingAway(f.mView); 1220990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.setStateAfterAnimating(newState); 122103526560f132021f8fd7290259762ab362d4d567Doris Liu final View viewToAnimate = f.mView; 122203526560f132021f8fd7290259762ab362d4d567Doris Liu anim.setAnimationListener(new AnimateOnHWLayerIfNeededListener( 122303526560f132021f8fd7290259762ab362d4d567Doris Liu viewToAnimate, anim) { 1224cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 1225cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void onAnimationEnd(Animation animation) { 122603526560f132021f8fd7290259762ab362d4d567Doris Liu super.onAnimationEnd(animation); 1227990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (fragment.getAnimatingAway() != null) { 1228990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.setAnimatingAway(null); 1229990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveToState(fragment, fragment.getStateAfterAnimating(), 12305506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn 0, 0, false); 1231cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1232cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1233cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn }); 12349277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn f.mView.startAnimation(anim); 1235cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 12368aa950177d9290b005f0817485f241ddc41c8026George Mount f.mContainer.removeView(f.mView); 1237cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1238cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mContainer = null; 1239cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mView = null; 1240cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mInnerView = null; 1241cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1242cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case Fragment.CREATED: 1243cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (newState < Fragment.CREATED) { 1244cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mDestroyed) { 1245990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.getAnimatingAway() != null) { 1246cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // The fragment's containing activity is 1247cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // being destroyed, but this fragment is 1248cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // currently animating away. Stop the 1249cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // animation right now -- it is not needed, 1250cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // and we can't wait any more on destroying 1251cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // the fragment. 1252990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount View v = f.getAnimatingAway(); 1253990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.setAnimatingAway(null); 1254cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn v.clearAnimation(); 1255cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1256cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1257990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.getAnimatingAway() != null) { 1258cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // We are waiting for the fragment's view to finish 1259cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // animating away. Just make a note of the state 1260cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // the fragment now should move to once the animation 1261cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // is done. 1262990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.setStateAfterAnimating(newState); 12632c4b5dbfee5232bcbbcb74b84ce9147b62a9d789Dianne Hackborn newState = Fragment.CREATED; 1264cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 1265cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "movefrom CREATED: " + f); 1266cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (!f.mRetaining) { 12670adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.performDestroy(); 126820735a45289fdad3d5d31228992e0dccd3d5dd4fAdam Powell } else { 1269b054427688e7cf0475bec09da9a3fb7688881459Adam Powell f.mState = Fragment.INITIALIZING; 1270cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1271cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1272916455675ddb34d0eb848b2355550268d82c3ce7Adam Powell f.performDetach(); 12735506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn if (!keepActive) { 12745506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn if (!f.mRetaining) { 12755506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn makeInactive(f); 12765506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn } else { 1277d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy f.mHost = null; 12786252d78085a07c9d6bb4645a4e8086bf23b0a49aTim Kilbourn f.mParentFragment = null; 12795506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn f.mFragmentManager = null; 12805506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn } 12812c4b5dbfee5232bcbbcb74b84ce9147b62a9d789Dianne Hackborn } 1282cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1283cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1284cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1285cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 128620735a45289fdad3d5d31228992e0dccd3d5dd4fAdam Powell 128720735a45289fdad3d5d31228992e0dccd3d5dd4fAdam Powell if (f.mState != newState) { 128820735a45289fdad3d5d31228992e0dccd3d5dd4fAdam Powell Log.w(TAG, "moveToState: Fragment state for " + f + " not updated inline; " 128920735a45289fdad3d5d31228992e0dccd3d5dd4fAdam Powell + "expected state " + newState + " found " + f.mState); 129020735a45289fdad3d5d31228992e0dccd3d5dd4fAdam Powell f.mState = newState; 129120735a45289fdad3d5d31228992e0dccd3d5dd4fAdam Powell } 1292cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1293dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1294cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn void moveToState(Fragment f) { 12955506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn moveToState(f, mCurState, 0, 0, false); 1296cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1297cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1298990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 1299990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Fragments that have been shown or hidden don't have their visibility changed or 1300990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * animations run during the {@link #showFragment(Fragment)} or {@link #hideFragment(Fragment)} 1301990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * calls. After fragments are brought to their final state in 1302990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@link #moveFragmentToExpectedState(Fragment)} the fragments that have been shown or 1303990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * hidden must have their visibility changed and their animations started here. 1304990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 1305990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param fragment The fragment with mHiddenChanged = true that should change its View's 1306990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * visibility and start the show or hide animation. 1307990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 1308990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount void completeShowHideFragment(final Fragment fragment) { 1309990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (fragment.mView != null) { 1310990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Animation anim = loadAnimation(fragment, fragment.getNextTransition(), 1311990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount !fragment.mHidden, fragment.getNextTransitionStyle()); 1312990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (anim != null) { 1313990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount setHWLayerAnimListenerIfAlpha(fragment.mView, anim); 1314990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.mView.startAnimation(anim); 1315990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount setHWLayerAnimListenerIfAlpha(fragment.mView, anim); 1316990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount anim.start(); 1317990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1318990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int visibility = fragment.mHidden ? View.GONE : View.VISIBLE; 1319990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.mView.setVisibility(visibility); 1320990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1321990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (fragment.mAdded && fragment.mHasMenu && fragment.mMenuVisible) { 1322990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mNeedMenuInvalidate = true; 1323990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1324990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.mHiddenChanged = false; 1325990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.onHiddenChanged(fragment.mHidden); 1326cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1327dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1328990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 1329990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Moves a fragment to its expected final state or the fragment manager's state, depending 1330990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * on whether the fragment manager's state is raised properly. 1331990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 1332990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param f The fragment to change. 1333990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 1334990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount void moveFragmentToExpectedState(Fragment f) { 1335990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f == null) { 1336990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return; 1337990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1338990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int nextState = mCurState; 1339990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.mRemoving) { 1340990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.isInBackStack()) { 1341990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount nextState = Fragment.CREATED; 1342990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } else { 1343990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount nextState = Fragment.INITIALIZING; 1344990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1345cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1346990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveToState(f, nextState, f.getNextTransition(), f.getNextTransitionStyle(), false); 13470adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn 1348990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.mView != null) { 1349990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Move the view if it is out of order 1350990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Fragment underFragment = findFragmentUnder(f); 1351990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (underFragment != null) { 1352990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final View underView = underFragment.mView; 1353990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // make sure this fragment is in the right order. 1354990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final ViewGroup container = f.mContainer; 1355990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int underIndex = container.indexOfChild(underView); 1356990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int viewIndex = container.indexOfChild(f.mView); 1357990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (viewIndex < underIndex) { 1358990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount container.removeViewAt(viewIndex); 1359990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount container.addView(f.mView, underIndex); 1360990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1361990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1362990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.mIsNewlyAdded && f.mContainer != null) { 1363990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Make it visible and run the animations 1364990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.mView.setVisibility(View.VISIBLE); 1365990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.mIsNewlyAdded = false; 1366990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // run animations: 1367990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Animation anim = loadAnimation(f, f.getNextTransition(), true, 1368990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.getNextTransitionStyle()); 1369990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (anim != null) { 1370990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount setHWLayerAnimListenerIfAlpha(f.mView, anim); 1371990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.mView.startAnimation(anim); 1372990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1373990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1374990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1375990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.mHiddenChanged) { 1376990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount completeShowHideFragment(f); 1377990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1378990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1379990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 1380990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount void moveToState(int newState) { 1381990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mHost == null && newState != Fragment.INITIALIZING) { 1382990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount throw new IllegalStateException("No activity"); 1383cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 13840adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn 1385cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mCurState = newState; 1386990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 1387cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mActive != null) { 1388abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell boolean loadersRunning = false; 1389990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 1390990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Must add them in the proper order. mActive fragments may be out of order 1391990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mAdded != null) { 1392990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int numAdded = mAdded.size(); 1393990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numAdded; i++) { 1394990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Fragment f = mAdded.get(i); 1395990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveFragmentToExpectedState(f); 1396990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.mLoaderManager != null) { 1397990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount loadersRunning |= f.mLoaderManager.hasRunningLoaders(); 1398990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1399990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1400990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1401990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 1402990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Now iterate through all active fragments. These will include those that are removed 1403990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // and detached. 1404990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int numActive = mActive.size(); 1405990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numActive; i++) { 1406cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mActive.get(i); 1407990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f != null && (f.mRemoving || f.mDetached) && !f.mIsNewlyAdded) { 1408990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveFragmentToExpectedState(f); 1409abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell if (f.mLoaderManager != null) { 1410abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell loadersRunning |= f.mLoaderManager.hasRunningLoaders(); 1411abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell } 1412cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1413cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1414cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1415abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell if (!loadersRunning) { 1416abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell startPendingDeferredFragments(); 1417abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell } 1418abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell 1419d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy if (mNeedMenuInvalidate && mHost != null && mCurState == Fragment.RESUMED) { 14208491eb62f621cd5de4b4caed839be09c77011f53Todd Kennedy mHost.onSupportInvalidateOptionsMenu(); 1421cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mNeedMenuInvalidate = false; 1422cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1423cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1424cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1425abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell 1426abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell void startPendingDeferredFragments() { 14271199ae7067cdf8cf3eb30c057a61ae71a0aea1e5Adam Powell if (mActive == null) return; 14281199ae7067cdf8cf3eb30c057a61ae71a0aea1e5Adam Powell 1429abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell for (int i=0; i<mActive.size(); i++) { 1430abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell Fragment f = mActive.get(i); 1431abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell if (f != null) { 1432abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell performPendingDeferredStart(f); 1433abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell } 1434abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell } 1435abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell } 1436dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1437cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn void makeActive(Fragment f) { 1438cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mIndex >= 0) { 1439cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return; 1440cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1441dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1442cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mAvailIndices == null || mAvailIndices.size() <= 0) { 1443cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mActive == null) { 1444cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mActive = new ArrayList<Fragment>(); 1445cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 14460adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.setIndex(mActive.size(), mParent); 1447cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mActive.add(f); 1448dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1449cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 14500adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.setIndex(mAvailIndices.remove(mAvailIndices.size()-1), mParent); 1451cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mActive.set(f.mIndex, f); 1452cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1453be2c79d9a5439922030d2a3846c81c61f0e16912Dianne Hackborn if (DEBUG) Log.v(TAG, "Allocated fragment index " + f); 1454cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1455dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1456cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn void makeInactive(Fragment f) { 1457cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mIndex < 0) { 1458cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return; 1459cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1460dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1461be2c79d9a5439922030d2a3846c81c61f0e16912Dianne Hackborn if (DEBUG) Log.v(TAG, "Freeing fragment index " + f); 1462cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mActive.set(f.mIndex, null); 1463cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mAvailIndices == null) { 1464cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAvailIndices = new ArrayList<Integer>(); 1465cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1466cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAvailIndices.add(f.mIndex); 1467d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy mHost.inactivateFragment(f.mWho); 14689c53b844bd525e6a04e17291efc38713893074cdDianne Hackborn f.initState(); 1469cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1470dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1471cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void addFragment(Fragment fragment, boolean moveToStateNow) { 1472cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mAdded == null) { 1473cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAdded = new ArrayList<Fragment>(); 1474cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1475cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "add: " + fragment); 1476e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn makeActive(fragment); 1477e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (!fragment.mDetached) { 14783a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn if (mAdded.contains(fragment)) { 14793a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn throw new IllegalStateException("Fragment already added: " + fragment); 14803a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn } 1481e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn mAdded.add(fragment); 1482e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn fragment.mAdded = true; 1483e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn fragment.mRemoving = false; 1484990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (fragment.mView == null) { 1485990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.mHiddenChanged = false; 1486990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 14872a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn if (fragment.mHasMenu && fragment.mMenuVisible) { 1488e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn mNeedMenuInvalidate = true; 1489e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1490e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (moveToStateNow) { 1491e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn moveToState(fragment); 1492e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1493cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1494cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1495dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1496990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void removeFragment(Fragment fragment) { 1497cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "remove: " + fragment + " nesting=" + fragment.mBackStackNesting); 1498e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn final boolean inactive = !fragment.isInBackStack(); 1499e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (!fragment.mDetached || inactive) { 1500464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mAdded != null) { 1501464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn mAdded.remove(fragment); 1502464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn } 15032a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn if (fragment.mHasMenu && fragment.mMenuVisible) { 1504e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn mNeedMenuInvalidate = true; 1505e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1506e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn fragment.mAdded = false; 1507e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn fragment.mRemoving = true; 1508cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1509cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1510dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1511990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 1512990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Marks a fragment as hidden to be later animated in with 1513990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@link #completeShowHideFragment(Fragment)}. 1514990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 1515990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param fragment The fragment to be shown. 1516990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 1517990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void hideFragment(Fragment fragment) { 1518cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "hide: " + fragment); 1519cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (!fragment.mHidden) { 1520cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fragment.mHidden = true; 1521990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Toggle hidden changed so that if a fragment goes through show/hide/show 1522990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // it doesn't go through the animation. 1523990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.mHiddenChanged = !fragment.mHiddenChanged; 1524cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1525cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1526dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1527990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 1528990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Marks a fragment as shown to be later animated in with 1529990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@link #completeShowHideFragment(Fragment)}. 1530990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 1531990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param fragment The fragment to be shown. 1532990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 1533990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void showFragment(Fragment fragment) { 1534cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "show: " + fragment); 1535cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (fragment.mHidden) { 1536cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fragment.mHidden = false; 1537990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Toggle hidden changed so that if a fragment goes through show/hide/show 1538990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // it doesn't go through the animation. 1539990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.mHiddenChanged = !fragment.mHiddenChanged; 1540cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1541cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1542dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1543990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void detachFragment(Fragment fragment) { 1544e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (DEBUG) Log.v(TAG, "detach: " + fragment); 1545e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (!fragment.mDetached) { 1546e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn fragment.mDetached = true; 1547e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (fragment.mAdded) { 1548e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn // We are not already in back stack, so need to remove the fragment. 1549464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mAdded != null) { 15503a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn if (DEBUG) Log.v(TAG, "remove from detach: " + fragment); 1551464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn mAdded.remove(fragment); 1552464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn } 15532a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn if (fragment.mHasMenu && fragment.mMenuVisible) { 1554e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn mNeedMenuInvalidate = true; 1555e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1556e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn fragment.mAdded = false; 1557e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1558e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1559e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1560e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn 1561990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void attachFragment(Fragment fragment) { 1562e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (DEBUG) Log.v(TAG, "attach: " + fragment); 1563e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (fragment.mDetached) { 1564e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn fragment.mDetached = false; 1565e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (!fragment.mAdded) { 1566464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mAdded == null) { 1567464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn mAdded = new ArrayList<Fragment>(); 1568464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn } 15693a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn if (mAdded.contains(fragment)) { 15703a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn throw new IllegalStateException("Fragment already added: " + fragment); 15713a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn } 15723a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn if (DEBUG) Log.v(TAG, "add from attach: " + fragment); 1573e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn mAdded.add(fragment); 1574e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn fragment.mAdded = true; 15752a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn if (fragment.mHasMenu && fragment.mMenuVisible) { 1576e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn mNeedMenuInvalidate = true; 1577e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1578e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1579e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1580e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1581e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn 158290ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas @Override 1583cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public Fragment findFragmentById(int id) { 1584464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mAdded != null) { 1585cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // First look through added fragments. 1586cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=mAdded.size()-1; i>=0; i--) { 1587cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mAdded.get(i); 1588cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f != null && f.mFragmentId == id) { 1589cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return f; 1590cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1591cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1592464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn } 1593464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mActive != null) { 1594cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Now for any known fragment. 1595cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=mActive.size()-1; i>=0; i--) { 1596cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mActive.get(i); 1597cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f != null && f.mFragmentId == id) { 1598cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return f; 1599cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1600cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1601cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1602cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 1603cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 160490ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas 160590ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas @Override 1606cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public Fragment findFragmentByTag(String tag) { 1607464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mAdded != null && tag != null) { 1608cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // First look through added fragments. 1609cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=mAdded.size()-1; i>=0; i--) { 1610cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mAdded.get(i); 1611cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f != null && tag.equals(f.mTag)) { 1612cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return f; 1613cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1614cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1615464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn } 1616464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mActive != null && tag != null) { 1617cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Now for any known fragment. 1618cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=mActive.size()-1; i>=0; i--) { 1619cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mActive.get(i); 1620cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f != null && tag.equals(f.mTag)) { 1621cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return f; 1622cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1623cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1624cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1625cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 1626cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1627dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1628cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public Fragment findFragmentByWho(String who) { 1629cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mActive != null && who != null) { 1630cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=mActive.size()-1; i>=0; i--) { 1631cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mActive.get(i); 16320adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (f != null && (f=f.findFragmentByWho(who)) != null) { 1633cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return f; 1634cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1635cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1636cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1637cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 1638cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1639dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1640cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn private void checkStateLoss() { 1641cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mStateSaved) { 1642cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn throw new IllegalStateException( 1643cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn "Can not perform this action after onSaveInstanceState"); 1644cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1645cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mNoTransactionsBecause != null) { 1646cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn throw new IllegalStateException( 1647cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn "Can not perform this action inside of " + mNoTransactionsBecause); 1648cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1649cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1650cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1651ab6e5dbcc6e05994ebb4257478c54f54085b9aa6Alan Viverette /** 1652ab6e5dbcc6e05994ebb4257478c54f54085b9aa6Alan Viverette * Adds an action to the queue of pending actions. 1653ab6e5dbcc6e05994ebb4257478c54f54085b9aa6Alan Viverette * 1654ab6e5dbcc6e05994ebb4257478c54f54085b9aa6Alan Viverette * @param action the action to add 1655ab6e5dbcc6e05994ebb4257478c54f54085b9aa6Alan Viverette * @param allowStateLoss whether to allow loss of state information 1656ab6e5dbcc6e05994ebb4257478c54f54085b9aa6Alan Viverette * @throws IllegalStateException if the activity has been destroyed 1657ab6e5dbcc6e05994ebb4257478c54f54085b9aa6Alan Viverette */ 1658990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void enqueueAction(OpGenerator action, boolean allowStateLoss) { 1659cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (!allowStateLoss) { 1660cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn checkStateLoss(); 1661cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1662cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn synchronized (this) { 1663d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy if (mDestroyed || mHost == null) { 1664cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn throw new IllegalStateException("Activity has been destroyed"); 1665cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1666cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mPendingActions == null) { 1667990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mPendingActions = new ArrayList<>(); 1668cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1669cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mPendingActions.add(action); 1670990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount scheduleCommit(); 1671990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1672990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1673990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 1674990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 1675990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Schedules the execution when one hasn't been scheduled already. This should happen 1676990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * the first time {@link #enqueueAction(OpGenerator, boolean)} is called or when 1677990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * a postponed transaction has been started with 1678990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@link Fragment#startPostponedEnterTransition()} 1679990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 1680990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void scheduleCommit() { 1681990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount synchronized (this) { 1682990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean postponeReady = 1683990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mPostponedTransactions != null && !mPostponedTransactions.isEmpty(); 1684990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean pendingReady = mPendingActions != null && mPendingActions.size() == 1; 1685990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (postponeReady || pendingReady) { 1686d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy mHost.getHandler().removeCallbacks(mExecCommit); 1687d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy mHost.getHandler().post(mExecCommit); 1688cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1689cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1690cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1691dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1692cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public int allocBackStackIndex(BackStackRecord bse) { 1693cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn synchronized (this) { 1694cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mAvailBackStackIndices == null || mAvailBackStackIndices.size() <= 0) { 1695cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStackIndices == null) { 1696cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackIndices = new ArrayList<BackStackRecord>(); 1697cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1698cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int index = mBackStackIndices.size(); 1699cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Setting back stack index " + index + " to " + bse); 1700cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackIndices.add(bse); 1701cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return index; 1702cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1703cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 1704cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int index = mAvailBackStackIndices.remove(mAvailBackStackIndices.size()-1); 1705cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Adding back stack index " + index + " with " + bse); 1706cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackIndices.set(index, bse); 1707cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return index; 1708cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1709cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1710cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1711cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1712cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void setBackStackIndex(int index, BackStackRecord bse) { 1713cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn synchronized (this) { 1714cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStackIndices == null) { 1715cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackIndices = new ArrayList<BackStackRecord>(); 1716cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1717cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int N = mBackStackIndices.size(); 1718cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (index < N) { 1719cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Setting back stack index " + index + " to " + bse); 1720cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackIndices.set(index, bse); 1721cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 1722cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn while (N < index) { 1723cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackIndices.add(null); 1724cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mAvailBackStackIndices == null) { 1725cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAvailBackStackIndices = new ArrayList<Integer>(); 1726cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1727cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Adding available back stack index " + N); 1728cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAvailBackStackIndices.add(N); 1729cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn N++; 1730cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1731cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Adding back stack index " + index + " with " + bse); 1732cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackIndices.add(bse); 1733cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1734cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1735cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1736cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1737cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void freeBackStackIndex(int index) { 1738cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn synchronized (this) { 1739cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackIndices.set(index, null); 1740cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mAvailBackStackIndices == null) { 1741cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAvailBackStackIndices = new ArrayList<Integer>(); 1742cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1743cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Freeing back stack index " + index); 1744cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAvailBackStackIndices.add(index); 1745cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1746cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1747cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1748990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 1749990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Broken out from exec*, this prepares for gathering and executing operations. 1750990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 1751990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param allowStateLoss true if state loss should be ignored or false if it should be 1752990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * checked. 1753990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 1754990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void ensureExecReady(boolean allowStateLoss) { 1755e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell if (mExecutingActions) { 1756e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell throw new IllegalStateException("FragmentManager is already executing transactions"); 1757e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell } 1758e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell 1759e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell if (Looper.myLooper() != mHost.getHandler().getLooper()) { 1760e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell throw new IllegalStateException("Must be called from main thread of fragment host"); 1761e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell } 1762e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell 1763e880475b147312ca62bed05bbeb37ec820d693aeAdam Powell if (!allowStateLoss) { 1764e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell checkStateLoss(); 1765e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell } 1766e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell 1767990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mTmpRecords == null) { 1768990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mTmpRecords = new ArrayList<>(); 1769990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mTmpIsPop = new ArrayList<>(); 1770990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1771990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount executePostponedTransaction(null, null); 1772990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1773990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 1774990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void execSingleAction(OpGenerator action, boolean allowStateLoss) { 1775990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ensureExecReady(allowStateLoss); 1776990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (action.generateOps(mTmpRecords, mTmpIsPop)) { 1777990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mExecutingActions = true; 1778990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount try { 1779990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount optimizeAndExecuteOps(mTmpRecords, mTmpIsPop); 1780990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } finally { 1781990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount cleanupExec(); 1782990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1783990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1784e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell 1785e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell doPendingDeferredStart(); 1786e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell } 1787e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell 1788cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 1789990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Broken out of exec*, this cleans up the mExecutingActions and the temporary structures 1790990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * used in executing operations. 1791990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 1792990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void cleanupExec() { 1793990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mExecutingActions = false; 1794990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mTmpIsPop.clear(); 1795990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mTmpRecords.clear(); 1796990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1797990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 1798990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 1799cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Only call from main thread! 1800cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 1801cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean execPendingActions() { 1802990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ensureExecReady(true); 1803990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 1804990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean didSomething = false; 1805990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) { 1806990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mExecutingActions = true; 1807990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount try { 1808990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount optimizeAndExecuteOps(mTmpRecords, mTmpIsPop); 1809990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } finally { 1810990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount cleanupExec(); 1811990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1812990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount didSomething = true; 1813cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1814dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1815990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount doPendingDeferredStart(); 1816990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 1817990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return didSomething; 1818990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1819990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 1820990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 1821990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Complete the execution of transactions that have previously been postponed, but are 1822990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * now ready. 1823990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 1824990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void executePostponedTransaction(ArrayList<BackStackRecord> records, 1825990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Boolean> isRecordPop) { 1826990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int numPostponed = mPostponedTransactions == null ? 0 : mPostponedTransactions.size(); 1827990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numPostponed; i++) { 1828990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount StartEnterTransitionListener listener = mPostponedTransactions.get(i); 1829990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (records != null && !listener.mIsBack) { 1830990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int index = records.indexOf(listener.mRecord); 1831990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (index != -1 && isRecordPop.get(index)) { 1832990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount listener.cancelTransaction(); 1833990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount continue; 1834990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1835990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1836990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (listener.isReady() || (records != null 1837990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount && listener.mRecord.interactsWith(records, 0, records.size()))) { 1838990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mPostponedTransactions.remove(i); 1839990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount i--; 1840990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount numPostponed--; 1841990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int index; 1842990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (records != null && !listener.mIsBack 1843990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount && (index = records.indexOf(listener.mRecord)) != -1 1844990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount && isRecordPop.get(index)) { 1845990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // This is popping a postponed transaction 1846990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount listener.cancelTransaction(); 1847990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } else { 1848990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount listener.completeTransaction(); 1849990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1850990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1851cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1852990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1853cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1854990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 1855990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Optimizes BackStackRecord operations. This method merges operations of proximate records 1856990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * that allow optimization. See {@link FragmentTransaction#setAllowOptimization(boolean)}. 1857990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * <p> 1858990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * For example, a transaction that adds to the back stack and then another that pops that 1859990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * back stack record will be optimized. 1860990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * <p> 1861990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Likewise, two transactions committed that are executed at the same time will be optimized 1862990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * as well as two pop operations executed together. 1863990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 1864990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param records The records pending execution 1865990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param isRecordPop The direction that these records are being run. 1866990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 1867990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void optimizeAndExecuteOps(ArrayList<BackStackRecord> records, 1868990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Boolean> isRecordPop) { 1869990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (records == null || records.isEmpty()) { 1870990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return; 1871990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1872990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 1873990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (isRecordPop == null || records.size() != isRecordPop.size()) { 1874990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount throw new IllegalStateException("Internal error with the back stack records"); 1875990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1876990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 1877990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Force start of any postponed transactions that interact with scheduled transactions: 1878990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount executePostponedTransaction(records, isRecordPop); 1879990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 1880990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int numRecords = records.size(); 1881990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int startIndex = 0; 1882990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int recordNum = 0; recordNum < numRecords; recordNum++) { 1883990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final boolean canOptimize = records.get(recordNum).mAllowOptimization; 1884990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (!canOptimize) { 1885990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // execute all previous transactions 1886990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (startIndex != recordNum) { 1887990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount executeOpsTogether(records, isRecordPop, startIndex, recordNum); 1888990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1889990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // execute all unoptimized together 1890990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int optimizeEnd; 1891990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (optimizeEnd = recordNum + 1; optimizeEnd < numRecords; optimizeEnd++) { 1892990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (records.get(optimizeEnd).mAllowOptimization) { 1893990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount break; 1894990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1895990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1896990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount executeOpsTogether(records, isRecordPop, recordNum, optimizeEnd); 1897990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount startIndex = optimizeEnd; 1898990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount recordNum = optimizeEnd - 1; 1899990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1900990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1901990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (startIndex != numRecords) { 1902990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount executeOpsTogether(records, isRecordPop, startIndex, numRecords); 1903990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1904990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1905990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 1906990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 1907990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Optimizes a subset of a list of BackStackRecords, all of which either allow optimization or 1908990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * do not allow optimization. 1909990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param records A list of BackStackRecords that are to be optimized 1910990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param isRecordPop The direction that these records are being run. 1911990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param startIndex The index of the first record in <code>records</code> to be optimized 1912990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param endIndex One more than the final record index in <code>records</code> to optimize. 1913990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 1914990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void executeOpsTogether(ArrayList<BackStackRecord> records, 1915990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) { 1916990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final boolean allowOptimization = records.get(startIndex).mAllowOptimization; 1917990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean addToBackStack = false; 1918990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mTmpAddedFragments == null) { 1919990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mTmpAddedFragments = new ArrayList<>(); 1920990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } else { 1921990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mTmpAddedFragments.clear(); 1922990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1923990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mAdded != null) { 1924990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mTmpAddedFragments.addAll(mAdded); 1925990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1926990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int recordNum = startIndex; recordNum < endIndex; recordNum++) { 1927990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final BackStackRecord record = records.get(recordNum); 1928990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final boolean isPop = isRecordPop.get(recordNum); 1929990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (!isPop) { 1930990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount record.expandReplaceOps(mTmpAddedFragments); 1931990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1932990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int bumpAmount = isPop ? -1 : 1; 1933990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount record.bumpBackStackNesting(bumpAmount); 1934990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount addToBackStack = addToBackStack || record.mAddToBackStack; 1935990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1936990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mTmpAddedFragments.clear(); 1937990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 1938990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (!allowOptimization) { 1939990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTransition.startTransitions(this, records, isRecordPop, startIndex, endIndex, 1940990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount false); 1941990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1942990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount executeOps(records, isRecordPop, startIndex, endIndex); 1943cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1944990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int postponeIndex = endIndex; 1945990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (allowOptimization) { 1946990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveFragmentsToInvisible(); 1947990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount postponeIndex = postponePostponableTransactions(records, isRecordPop, 1948990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount startIndex, endIndex); 1949990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1950990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 1951990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (postponeIndex != startIndex && allowOptimization) { 1952990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // need to run something now 1953990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTransition.startTransitions(this, records, isRecordPop, startIndex, 1954990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount postponeIndex, true); 1955990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveToState(mCurState); 1956990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1957990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 1958990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int recordNum = startIndex; recordNum < endIndex; recordNum++) { 1959990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final BackStackRecord record = records.get(recordNum); 1960990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final boolean isPop = isRecordPop.get(recordNum); 1961990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (isPop && record.mIndex >= 0) { 1962990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount freeBackStackIndex(record.mIndex); 1963990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount record.mIndex = -1; 1964990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1965990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1966990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (addToBackStack) { 1967990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount reportBackStackChanged(); 1968990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1969990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1970dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1971990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 1972990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Examine all transactions and determine which ones are marked as postponed. Those will 1973990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * have their operations rolled back and moved to the end of the record list (up to endIndex). 1974990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * It will also add the postponed transaction to the queue. 1975990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 1976990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param records A list of BackStackRecords that should be checked. 1977990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param isRecordPop The direction that these records are being run. 1978990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param startIndex The index of the first record in <code>records</code> to be checked 1979990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param endIndex One more than the final record index in <code>records</code> to be checked. 1980990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @return The index of the first postponed transaction or endIndex if no transaction was 1981990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * postponed. 1982990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 1983990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private int postponePostponableTransactions(ArrayList<BackStackRecord> records, 1984990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) { 1985990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int postponeIndex = endIndex; 1986990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = endIndex - 1; i >= startIndex; i--) { 1987990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final BackStackRecord record = records.get(i); 1988990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final boolean isPop = isRecordPop.get(i); 1989990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean isPostponed = record.isPostponed() 1990990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount && !record.interactsWith(records, i + 1, endIndex); 1991990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (isPostponed) { 1992990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mPostponedTransactions == null) { 1993990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mPostponedTransactions = new ArrayList<>(); 1994990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1995990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount StartEnterTransitionListener listener = 1996990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount new StartEnterTransitionListener(record, isPop); 1997990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mPostponedTransactions.add(listener); 1998990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount record.setOnStartPostponedListener(listener); 1999990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2000990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // roll back the transaction 2001990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (isPop) { 2002990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount record.executeOps(); 2003990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } else { 2004990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount record.executePopOps(); 2005cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2006dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2007990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // move to the end 2008990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount postponeIndex--; 2009990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (i != postponeIndex) { 2010990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount records.remove(i); 2011990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount records.add(postponeIndex, record); 2012cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2013990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2014990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // different views may be visible now 2015990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveFragmentsToInvisible(); 2016cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2017990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2018990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return postponeIndex; 2019990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2020dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2021990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2022990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * When a postponed transaction is ready to be started, this completes the transaction, 2023990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * removing, hiding, or showing views as well as starting the animations and transitions. 2024990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * <p> 2025990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@code runtransitions} is set to false when the transaction postponement was interrupted 2026990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * abnormally -- normally by a new transaction being started that affects the postponed 2027990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * transaction. 2028990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 2029990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param record The transaction to run 2030990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param isPop true if record is popping or false if it is adding 2031990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param runTransitions true if the fragment transition should be run or false otherwise. 2032990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param moveToState true if the state should be changed after executing the operations. 2033990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * This is false when the transaction is canceled when a postponed 2034990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * transaction is popped. 2035990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2036990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void completeExecute(BackStackRecord record, boolean isPop, boolean runTransitions, 2037990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean moveToState) { 2038990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<BackStackRecord> records = new ArrayList<>(1); 2039990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Boolean> isRecordPop = new ArrayList<>(1); 2040990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount records.add(record); 2041990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount isRecordPop.add(isPop); 2042990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount executeOps(records, isRecordPop, 0, 1); 2043990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (runTransitions) { 2044990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTransition.startTransitions(this, records, isRecordPop, 0, 1, true); 2045990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2046990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (moveToState) { 2047990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveToState(mCurState); 2048990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } else if (mActive != null) { 2049990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int numActive = mActive.size(); 2050990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numActive; i++) { 2051990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Allow added fragments to be removed during the pop since we aren't going 2052990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // to move them to the final state with moveToState(mCurState). 2053990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Fragment fragment = mActive.get(i); 2054990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (fragment.mView != null && fragment.mIsNewlyAdded 2055990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount && record.interactsWith(fragment.mContainerId)) { 2056990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.mIsNewlyAdded = false; 2057990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2058cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2059cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2060990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2061dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2062990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2063990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Find a fragment within the fragment's container whose View should be below the passed 2064990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * fragment. {@code null} is returned when the fragment has no View or if there should be 2065990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * no fragment with a View below the given fragment. 2066990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 2067990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * As an example, if mAdded has two Fragments with Views sharing the same container: 2068990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * FragmentA 2069990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * FragmentB 2070990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 2071990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Then, when processing FragmentB, FragmentA will be returned. If, however, FragmentA 2072990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * had no View, null would be returned. 2073990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 2074990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param f The fragment that may be on top of another fragment. 2075990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @return The fragment with a View under f, if one exists or null if f has no View or 2076990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * there are no fragments with Views in the same container. 2077990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2078990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private Fragment findFragmentUnder(Fragment f) { 2079990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final ViewGroup container = f.mContainer; 2080990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final View view = f.mView; 2081e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell 2082990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (container == null || view == null) { 2083990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return null; 2084990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2085990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2086990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int fragmentIndex = mAdded.indexOf(f); 2087990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = fragmentIndex - 1; i >= 0; i--) { 2088990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Fragment underFragment = mAdded.get(i); 2089990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (underFragment.mContainer == container && underFragment.mView != null) { 2090990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Found the fragment under this one 2091990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return underFragment; 2092990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2093990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2094990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return null; 2095990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2096990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2097990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2098990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Run the operations in the BackStackRecords, either to push or pop. 2099990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 2100990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param records The list of records whose operations should be run. 2101990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param isRecordPop The direction that these records are being run. 2102990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param startIndex The index of the first entry in records to run. 2103990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param endIndex One past the index of the final entry in records to run. 2104990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2105990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private static void executeOps(ArrayList<BackStackRecord> records, 2106990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) { 2107990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = startIndex; i < endIndex; i++) { 2108990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final BackStackRecord record = records.get(i); 2109990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final boolean isPop = isRecordPop.get(i); 2110990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (isPop) { 2111990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount record.executePopOps(); 2112990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } else { 2113990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount record.executeOps(); 2114990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2115990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2116990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2117990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2118990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2119990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Ensure that fragments that are added are moved to at least the CREATED state. 2120990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Any newly-added Views are made INVISIBLE so that the Transaction can be postponed 2121990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * with {@link Fragment#postponeEnterTransition()}. 2122990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2123990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void moveFragmentsToInvisible() { 2124990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mCurState < Fragment.CREATED) { 2125990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return; 2126990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2127990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // We want to leave the fragment in the started state 2128990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int state = Math.min(mCurState, Fragment.STARTED); 2129990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int numAdded = mAdded == null ? 0 : mAdded.size(); 2130990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numAdded; i++) { 2131990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Fragment fragment = mAdded.get(i); 2132990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (fragment.mState < state) { 2133990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveToState(fragment, state, fragment.getNextAnim(), fragment.getNextTransition(), 2134990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount false); 2135990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (fragment.mView != null && !fragment.mHidden && fragment.mIsNewlyAdded) { 2136990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.mView.setVisibility(View.INVISIBLE); 2137990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2138990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2139990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2140990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2141990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2142990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2143990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Starts all postponed transactions regardless of whether they are ready or not. 2144990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2145990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void forcePostponedTransactions() { 2146990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mPostponedTransactions != null) { 2147990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount while (!mPostponedTransactions.isEmpty()) { 2148990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mPostponedTransactions.remove(0).completeTransaction(); 2149990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2150990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2151990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2152990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2153990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2154990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Ends the animations of fragments so that they immediately reach the end state. 2155990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * This is used prior to saving the state so that the correct state is saved. 2156990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2157990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void endAnimatingAwayFragments() { 2158990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int numFragments = mActive == null ? 0 : mActive.size(); 2159990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numFragments; i++) { 2160990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Fragment fragment = mActive.get(i); 2161990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (fragment != null && fragment.getAnimatingAway() != null) { 2162990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Give up waiting for the animation and just end it. 2163990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int stateAfterAnimating = fragment.getStateAfterAnimating(); 2164990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final View animatingAway = fragment.getAnimatingAway(); 2165990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.setAnimatingAway(null); 2166990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount animatingAway.clearAnimation(); 2167990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveToState(fragment, stateAfterAnimating, 0, 0, false); 2168990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2169990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2170990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2171990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2172990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2173990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Adds all records in the pending actions to records and whether they are add or pop 2174990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * operations to isPop. After executing, the pending actions will be empty. 2175990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 2176990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param records All pending actions will generate BackStackRecords added to this. 2177990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * This contains the transactions, in order, to execute. 2178990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param isPop All pending actions will generate booleans to add to this. This contains 2179990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * an entry for each entry in records to indicate whether or not it is a 2180990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * pop action. 2181990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2182990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private boolean generateOpsForPendingActions(ArrayList<BackStackRecord> records, 2183990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Boolean> isPop) { 2184990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int numActions; 2185990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount synchronized (this) { 2186990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mPendingActions == null || mPendingActions.size() == 0) { 2187990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return false; 2188990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2189990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2190990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount numActions = mPendingActions.size(); 2191990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numActions; i++) { 2192990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mPendingActions.get(i).generateOps(records, isPop); 2193990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2194990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mPendingActions.clear(); 2195990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mHost.getHandler().removeCallbacks(mExecCommit); 2196990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2197990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return numActions > 0; 2198e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell } 2199e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell 2200e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell void doPendingDeferredStart() { 220179398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell if (mHavePendingDeferredStart) { 220279398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell boolean loadersRunning = false; 2203e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell for (int i = 0; i < mActive.size(); i++) { 220479398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell Fragment f = mActive.get(i); 220579398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell if (f != null && f.mLoaderManager != null) { 220679398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell loadersRunning |= f.mLoaderManager.hasRunningLoaders(); 220779398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell } 220879398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell } 220979398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell if (!loadersRunning) { 221079398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell mHavePendingDeferredStart = false; 221179398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell startPendingDeferredFragments(); 221279398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell } 221379398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell } 2214cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 221579398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell 2216cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn void reportBackStackChanged() { 2217cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStackChangeListeners != null) { 2218cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<mBackStackChangeListeners.size(); i++) { 2219cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackChangeListeners.get(i).onBackStackChanged(); 2220cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2221cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2222cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2223cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2224cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn void addBackStackState(BackStackRecord state) { 2225cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStack == null) { 2226cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStack = new ArrayList<BackStackRecord>(); 2227cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2228cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStack.add(state); 2229cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn reportBackStackChanged(); 2230cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2231dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2232d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy @SuppressWarnings("unused") 2233990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean popBackStackState(ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop, 2234990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount String name, int id, int flags) { 2235cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStack == null) { 2236cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return false; 2237cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2238990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (name == null && id < 0 && (flags & POP_BACK_STACK_INCLUSIVE) == 0) { 2239990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int last = mBackStack.size() - 1; 2240cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (last < 0) { 2241cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return false; 2242cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2243990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount records.add(mBackStack.remove(last)); 2244990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount isRecordPop.add(true); 2245cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 2246cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int index = -1; 2247cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (name != null || id >= 0) { 2248cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // If a name or ID is specified, look for that place in 2249cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // the stack. 2250cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn index = mBackStack.size()-1; 2251cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn while (index >= 0) { 2252cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn BackStackRecord bss = mBackStack.get(index); 2253cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (name != null && name.equals(bss.getName())) { 2254cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 2255cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2256cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (id >= 0 && id == bss.mIndex) { 2257cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 2258cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2259cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn index--; 2260cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2261cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (index < 0) { 2262cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return false; 2263cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2264cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if ((flags&POP_BACK_STACK_INCLUSIVE) != 0) { 2265cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn index--; 2266cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Consume all following entries that match. 2267cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn while (index >= 0) { 2268cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn BackStackRecord bss = mBackStack.get(index); 2269cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if ((name != null && name.equals(bss.getName())) 2270cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn || (id >= 0 && id == bss.mIndex)) { 2271cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn index--; 2272cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn continue; 2273cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2274cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 2275cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2276cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2277cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2278cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (index == mBackStack.size()-1) { 2279cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return false; 2280cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2281990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = mBackStack.size() - 1; i > index; i--) { 2282990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount records.add(mBackStack.remove(i)); 2283990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount isRecordPop.add(true); 2284cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2285cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2286cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return true; 2287cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2288dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2289c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell FragmentManagerNonConfig retainNonConfig() { 2290cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ArrayList<Fragment> fragments = null; 2291c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell ArrayList<FragmentManagerNonConfig> childFragments = null; 2292cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mActive != null) { 2293cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<mActive.size(); i++) { 2294cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mActive.get(i); 2295c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell if (f != null) { 2296c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell if (f.mRetainInstance) { 2297c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell if (fragments == null) { 2298c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell fragments = new ArrayList<Fragment>(); 2299c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell } 2300c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell fragments.add(f); 2301c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell f.mRetaining = true; 2302c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell f.mTargetIndex = f.mTarget != null ? f.mTarget.mIndex : -1; 2303c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell if (DEBUG) Log.v(TAG, "retainNonConfig: keeping retained " + f); 2304c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell } 2305c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell boolean addedChild = false; 2306c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell if (f.mChildFragmentManager != null) { 2307c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell FragmentManagerNonConfig child = f.mChildFragmentManager.retainNonConfig(); 2308c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell if (child != null) { 2309c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell if (childFragments == null) { 2310c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell childFragments = new ArrayList<FragmentManagerNonConfig>(); 2311c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell for (int j = 0; j < i; j++) { 2312c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell childFragments.add(null); 2313c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell } 2314c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell } 2315c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell childFragments.add(child); 2316c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell addedChild = true; 2317c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell } 2318c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell } 2319c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell if (childFragments != null && !addedChild) { 2320c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell childFragments.add(null); 2321cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2322cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2323cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2324cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2325c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell if (fragments == null && childFragments == null) { 2326c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell return null; 2327c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell } 2328c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell return new FragmentManagerNonConfig(fragments, childFragments); 2329cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2330dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2331cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn void saveFragmentViewState(Fragment f) { 2332cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mInnerView == null) { 2333cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return; 2334cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2335cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mStateArray == null) { 2336cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mStateArray = new SparseArray<Parcelable>(); 2337ea2c91b0198855073983b4a8437aa71cbd83872fDianne Hackborn } else { 2338ea2c91b0198855073983b4a8437aa71cbd83872fDianne Hackborn mStateArray.clear(); 2339cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2340cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mInnerView.saveHierarchyState(mStateArray); 2341cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mStateArray.size() > 0) { 2342cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mSavedViewState = mStateArray; 2343cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mStateArray = null; 2344cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2345cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2346dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 23475c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn Bundle saveFragmentBasicState(Fragment f) { 23485c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn Bundle result = null; 23495c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn 23505c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn if (mStateBundle == null) { 23515c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn mStateBundle = new Bundle(); 23525c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 23530adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.performSaveInstanceState(mStateBundle); 23545c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn if (!mStateBundle.isEmpty()) { 23555c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn result = mStateBundle; 23565c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn mStateBundle = null; 23575c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 23585c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn 23595c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn if (f.mView != null) { 23605c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn saveFragmentViewState(f); 23615c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 23625c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn if (f.mSavedViewState != null) { 23635c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn if (result == null) { 23645c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn result = new Bundle(); 23655c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 23665c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn result.putSparseParcelableArray( 23675c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn FragmentManagerImpl.VIEW_STATE_TAG, f.mSavedViewState); 23685c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 236979398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell if (!f.mUserVisibleHint) { 2370f4c0cf637ba73374a206cec26c09d4dfa4c1a364Jake Wharton if (result == null) { 2371f4c0cf637ba73374a206cec26c09d4dfa4c1a364Jake Wharton result = new Bundle(); 2372f4c0cf637ba73374a206cec26c09d4dfa4c1a364Jake Wharton } 237379398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell // Only add this if it's not the default value 237479398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell result.putBoolean(FragmentManagerImpl.USER_VISIBLE_HINT_TAG, f.mUserVisibleHint); 237579398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell } 23765c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn 23775c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn return result; 23785c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 23795c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn 2380cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Parcelable saveAllState() { 2381cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Make sure all pending operations have now been executed to get 2382cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // our state update-to-date. 2383990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount forcePostponedTransactions(); 2384990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount endAnimatingAwayFragments(); 2385cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn execPendingActions(); 2386cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2387681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn if (HONEYCOMB) { 2388681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn // As of Honeycomb, we save state after pausing. Prior to that 2389681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn // it is before pausing. With fragments this is an issue, since 2390681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn // there are many things you may do after pausing but before 2391681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn // stopping that change the fragment state. For those older 2392681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn // devices, we will not at this point say that we have saved 2393681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn // the state, so we will allow them to continue doing fragment 2394681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn // transactions. This retains the same semantics as Honeycomb, 2395681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn // though you do have the risk of losing the very most recent state 2396681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn // if the process is killed... we'll live with that. 2397681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn mStateSaved = true; 2398681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn } 2399cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2400cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mActive == null || mActive.size() <= 0) { 2401cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 2402cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2403dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2404cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // First collect all active fragments. 2405cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int N = mActive.size(); 2406cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentState[] active = new FragmentState[N]; 2407cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn boolean haveFragments = false; 2408cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<N; i++) { 2409cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mActive.get(i); 2410cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f != null) { 24111b913519b1c03b084779851e81db2e1a11eb0b0dDianne Hackborn if (f.mIndex < 0) { 241213fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn throwException(new IllegalStateException( 241313fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn "Failure saving state: active " + f 241413fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn + " has cleared index: " + f.mIndex)); 24151b913519b1c03b084779851e81db2e1a11eb0b0dDianne Hackborn } 24161b913519b1c03b084779851e81db2e1a11eb0b0dDianne Hackborn 2417cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn haveFragments = true; 2418dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2419cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentState fs = new FragmentState(f); 2420cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn active[i] = fs; 2421dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2422cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mState > Fragment.INITIALIZING && fs.mSavedFragmentState == null) { 24235c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn fs.mSavedFragmentState = saveFragmentBasicState(f); 2424cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2425cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mTarget != null) { 2426cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mTarget.mIndex < 0) { 242713fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn throwException(new IllegalStateException( 242813fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn "Failure saving state: " + f 242913fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn + " has target not in fragment manager: " + f.mTarget)); 2430cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2431cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (fs.mSavedFragmentState == null) { 2432cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fs.mSavedFragmentState = new Bundle(); 2433cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2434cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn putFragment(fs.mSavedFragmentState, 2435cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentManagerImpl.TARGET_STATE_TAG, f.mTarget); 2436cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mTargetRequestCode != 0) { 2437cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fs.mSavedFragmentState.putInt( 2438cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 2439cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mTargetRequestCode); 2440cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2441cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2442cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2443cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 2444cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fs.mSavedFragmentState = f.mSavedFragmentState; 2445cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2446dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2447cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Saved state of " + f + ": " 2448cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn + fs.mSavedFragmentState); 2449cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2450cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2451dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2452cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (!haveFragments) { 2453cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "saveAllState: no fragments!"); 2454cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 2455cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2456dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2457cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int[] added = null; 2458cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn BackStackState[] backStack = null; 2459dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2460cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Build list of currently added fragments. 2461cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mAdded != null) { 2462cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn N = mAdded.size(); 2463cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (N > 0) { 2464cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn added = new int[N]; 2465cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<N; i++) { 2466cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn added[i] = mAdded.get(i).mIndex; 24671b913519b1c03b084779851e81db2e1a11eb0b0dDianne Hackborn if (added[i] < 0) { 246813fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn throwException(new IllegalStateException( 246913fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn "Failure saving state: active " + mAdded.get(i) 247013fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn + " has cleared index: " + added[i])); 24711b913519b1c03b084779851e81db2e1a11eb0b0dDianne Hackborn } 2472cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "saveAllState: adding fragment #" + i 2473cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn + ": " + mAdded.get(i)); 2474cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2475cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2476cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2477dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2478cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Now save back stack. 2479cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStack != null) { 2480cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn N = mBackStack.size(); 2481cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (N > 0) { 2482cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn backStack = new BackStackState[N]; 2483cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<N; i++) { 2484d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy backStack[i] = new BackStackState(mBackStack.get(i)); 2485cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "saveAllState: adding back stack #" + i 2486cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn + ": " + mBackStack.get(i)); 2487cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2488cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2489cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2490dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2491cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentManagerState fms = new FragmentManagerState(); 2492cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fms.mActive = active; 2493cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fms.mAdded = added; 2494cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fms.mBackStack = backStack; 2495cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return fms; 2496cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2497dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2498c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell void restoreAllState(Parcelable state, FragmentManagerNonConfig nonConfig) { 2499cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // If there is no saved state at all, then there can not be 2500cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // any nonConfig fragments either, so that is that. 2501cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (state == null) return; 2502cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentManagerState fms = (FragmentManagerState)state; 2503cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (fms.mActive == null) return; 2504c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell 2505c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell List<FragmentManagerNonConfig> childNonConfigs = null; 2506c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell 2507cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // First re-attach any non-config instances we are retaining back 2508cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // to their saved state, so we don't try to instantiate them again. 2509cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (nonConfig != null) { 2510c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell List<Fragment> nonConfigFragments = nonConfig.getFragments(); 2511c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell childNonConfigs = nonConfig.getChildNonConfigs(); 2512c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell final int count = nonConfigFragments != null ? nonConfigFragments.size() : 0; 2513c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell for (int i = 0; i < count; i++) { 2514c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell Fragment f = nonConfigFragments.get(i); 2515cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "restoreAllState: re-attaching retained " + f); 2516cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentState fs = fms.mActive[f.mIndex]; 2517cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fs.mInstance = f; 2518cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mSavedViewState = null; 2519cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mBackStackNesting = 0; 2520cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mInLayout = false; 2521cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mAdded = false; 25222c4b5dbfee5232bcbbcb74b84ce9147b62a9d789Dianne Hackborn f.mTarget = null; 2523cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (fs.mSavedFragmentState != null) { 2524d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy fs.mSavedFragmentState.setClassLoader(mHost.getContext().getClassLoader()); 2525cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mSavedViewState = fs.mSavedFragmentState.getSparseParcelableArray( 2526cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentManagerImpl.VIEW_STATE_TAG); 25278e4a59b54e9225b77151805dd6b8867dcd8e60a4Craig Mautner f.mSavedFragmentState = fs.mSavedFragmentState; 2528cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2529cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2530cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2531dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2532cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Build the full list of active fragments, instantiating them from 2533cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // their saved state. 2534c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell mActive = new ArrayList<>(fms.mActive.length); 2535cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mAvailIndices != null) { 2536cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAvailIndices.clear(); 2537cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2538cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<fms.mActive.length; i++) { 2539cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentState fs = fms.mActive[i]; 2540cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (fs != null) { 2541c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell FragmentManagerNonConfig childNonConfig = null; 2542c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell if (childNonConfigs != null && i < childNonConfigs.size()) { 2543c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell childNonConfig = childNonConfigs.get(i); 2544c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell } 2545c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell Fragment f = fs.instantiate(mHost, mParent, childNonConfig); 25463a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn if (DEBUG) Log.v(TAG, "restoreAllState: active #" + i + ": " + f); 2547cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mActive.add(f); 2548cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Now that the fragment is instantiated (or came from being 2549cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // retained above), clear mInstance in case we end up re-restoring 2550cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // from this FragmentState again. 2551cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fs.mInstance = null; 2552cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 2553cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mActive.add(null); 2554cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mAvailIndices == null) { 2555cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAvailIndices = new ArrayList<Integer>(); 2556cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 25573a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn if (DEBUG) Log.v(TAG, "restoreAllState: avail #" + i); 2558cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAvailIndices.add(i); 2559cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2560cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2561dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2562cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Update the target of all retained fragments. 2563cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (nonConfig != null) { 2564c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell List<Fragment> nonConfigFragments = nonConfig.getFragments(); 2565c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell final int count = nonConfigFragments != null ? nonConfigFragments.size() : 0; 2566c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell for (int i = 0; i < count; i++) { 2567c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell Fragment f = nonConfigFragments.get(i); 25682c4b5dbfee5232bcbbcb74b84ce9147b62a9d789Dianne Hackborn if (f.mTargetIndex >= 0) { 25692c4b5dbfee5232bcbbcb74b84ce9147b62a9d789Dianne Hackborn if (f.mTargetIndex < mActive.size()) { 25702c4b5dbfee5232bcbbcb74b84ce9147b62a9d789Dianne Hackborn f.mTarget = mActive.get(f.mTargetIndex); 2571cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 2572cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Log.w(TAG, "Re-attaching retained fragment " + f 25732c4b5dbfee5232bcbbcb74b84ce9147b62a9d789Dianne Hackborn + " target no longer exists: " + f.mTargetIndex); 2574cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mTarget = null; 2575cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2576cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2577cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2578cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2579cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2580cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Build the list of currently added fragments. 2581cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (fms.mAdded != null) { 2582cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAdded = new ArrayList<Fragment>(fms.mAdded.length); 2583cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<fms.mAdded.length; i++) { 2584cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mActive.get(fms.mAdded[i]); 2585cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f == null) { 258613fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn throwException(new IllegalStateException( 258713fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn "No instantiated fragment for index #" + fms.mAdded[i])); 2588cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2589cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mAdded = true; 25903a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn if (DEBUG) Log.v(TAG, "restoreAllState: added #" + i + ": " + f); 25913a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn if (mAdded.contains(f)) { 25923a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn throw new IllegalStateException("Already added!"); 25933a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn } 2594cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAdded.add(f); 2595cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2596cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 2597cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAdded = null; 2598cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2599dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2600cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Build the back stack. 2601cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (fms.mBackStack != null) { 2602cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStack = new ArrayList<BackStackRecord>(fms.mBackStack.length); 2603cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<fms.mBackStack.length; i++) { 2604cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn BackStackRecord bse = fms.mBackStack[i].instantiate(this); 26053a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn if (DEBUG) { 26063a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn Log.v(TAG, "restoreAllState: back stack #" + i 2607cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn + " (index " + bse.mIndex + "): " + bse); 26083a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn LogWriter logw = new LogWriter(TAG); 26093a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn PrintWriter pw = new PrintWriter(logw); 26103a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn bse.dump(" ", pw, false); 26113a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn } 2612cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStack.add(bse); 2613cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (bse.mIndex >= 0) { 2614cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn setBackStackIndex(bse.mIndex, bse); 2615cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2616cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2617cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 2618cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStack = null; 2619cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2620cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2621d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy 26228491eb62f621cd5de4b4caed839be09c77011f53Todd Kennedy public void attachController(FragmentHostCallback host, 26230adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn FragmentContainer container, Fragment parent) { 2624d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy if (mHost != null) throw new IllegalStateException("Already attached"); 2625d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy mHost = host; 26260adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn mContainer = container; 26270adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn mParent = parent; 2628cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2629dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2630cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void noteStateNotSaved() { 2631cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mStateSaved = false; 2632cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2633dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2634cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchCreate() { 2635cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mStateSaved = false; 2636990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveToState(Fragment.CREATED); 2637cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2638dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2639cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchActivityCreated() { 2640cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mStateSaved = false; 2641990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveToState(Fragment.ACTIVITY_CREATED); 2642cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2643dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2644cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchStart() { 2645cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mStateSaved = false; 2646990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveToState(Fragment.STARTED); 2647cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2648dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2649cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchResume() { 2650cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mStateSaved = false; 2651990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveToState(Fragment.RESUMED); 2652cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2653dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2654cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchPause() { 2655990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveToState(Fragment.STARTED); 2656cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2657dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2658cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchStop() { 2659681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn // See saveAllState() for the explanation of this. We do this for 2660681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn // all platform versions, to keep our behavior more consistent between 2661681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn // them. 2662681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn mStateSaved = true; 2663681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn 2664990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveToState(Fragment.STOPPED); 2665cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2666dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2667218c1e661578e2a17928f7dbb590b43d1c79aeb7Dianne Hackborn public void dispatchReallyStop() { 2668990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveToState(Fragment.ACTIVITY_CREATED); 2669681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn } 2670681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn 26710adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn public void dispatchDestroyView() { 2672990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveToState(Fragment.CREATED); 26730adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn } 26740adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn 2675cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchDestroy() { 2676cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mDestroyed = true; 2677e8b402b00c0cbdac050c349a5fc89c34580f3185Dianne Hackborn execPendingActions(); 2678990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveToState(Fragment.INITIALIZING); 2679d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy mHost = null; 26800adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn mContainer = null; 26810adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn mParent = null; 2682cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 26835fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian 26845fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian public void dispatchMultiWindowModeChanged(boolean isInMultiWindowMode) { 26855fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian if (mAdded == null) { 26865fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian return; 26875fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian } 26885fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian for (int i = mAdded.size() - 1; i >= 0; --i) { 26895fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian final android.support.v4.app.Fragment f = mAdded.get(i); 26905fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian if (f != null) { 26915fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian f.performMultiWindowModeChanged(isInMultiWindowMode); 26925fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian } 26935fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian } 26945fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian } 26955fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian 26965fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian public void dispatchPictureInPictureModeChanged(boolean isInPictureInPictureMode) { 26975fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian if (mAdded == null) { 26985fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian return; 26995fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian } 27005fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian for (int i = mAdded.size() - 1; i >= 0; --i) { 27015fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian final android.support.v4.app.Fragment f = mAdded.get(i); 27025fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian if (f != null) { 27035fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian f.performPictureInPictureModeChanged(isInPictureInPictureMode); 27045fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian } 27055fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian } 27065fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian } 27075fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian 2708cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchConfigurationChanged(Configuration newConfig) { 2709464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mAdded != null) { 2710cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<mAdded.size(); i++) { 2711cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mAdded.get(i); 2712cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f != null) { 27130adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.performConfigurationChanged(newConfig); 2714cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2715cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2716cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2717cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2718cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2719cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchLowMemory() { 2720464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mAdded != null) { 2721cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<mAdded.size(); i++) { 2722cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mAdded.get(i); 2723cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f != null) { 27240adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.performLowMemory(); 2725cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2726cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2727cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2728cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2729cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2730cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean dispatchCreateOptionsMenu(Menu menu, MenuInflater inflater) { 2731cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn boolean show = false; 2732cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ArrayList<Fragment> newMenus = null; 2733464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mAdded != null) { 2734cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<mAdded.size(); i++) { 2735cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mAdded.get(i); 27360adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (f != null) { 27370adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (f.performCreateOptionsMenu(menu, inflater)) { 27380adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn show = true; 27390adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (newMenus == null) { 27400adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn newMenus = new ArrayList<Fragment>(); 27410adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn } 27420adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn newMenus.add(f); 2743cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2744cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2745cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2746cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2747c1e87ac17c772ee3c5fd3b3f08321226e2c7ffa4Chris Banes 2748cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mCreatedMenus != null) { 2749cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<mCreatedMenus.size(); i++) { 2750cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mCreatedMenus.get(i); 2751cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (newMenus == null || !newMenus.contains(f)) { 2752cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.onDestroyOptionsMenu(); 2753cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2754cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2755cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2756c1e87ac17c772ee3c5fd3b3f08321226e2c7ffa4Chris Banes 2757cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mCreatedMenus = newMenus; 2758c1e87ac17c772ee3c5fd3b3f08321226e2c7ffa4Chris Banes 2759cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return show; 2760cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2761dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2762cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean dispatchPrepareOptionsMenu(Menu menu) { 2763cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn boolean show = false; 2764464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mAdded != null) { 2765cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<mAdded.size(); i++) { 2766cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mAdded.get(i); 27670adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (f != null) { 27680adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (f.performPrepareOptionsMenu(menu)) { 27690adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn show = true; 27700adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn } 2771cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2772cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2773cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2774cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return show; 2775cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2776dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2777cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean dispatchOptionsItemSelected(MenuItem item) { 2778464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mAdded != null) { 2779cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<mAdded.size(); i++) { 2780cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mAdded.get(i); 27810adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (f != null) { 27820adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (f.performOptionsItemSelected(item)) { 2783cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return true; 2784cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2785cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2786cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2787cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2788cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return false; 2789cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2790dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2791cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean dispatchContextItemSelected(MenuItem item) { 2792464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mAdded != null) { 2793cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<mAdded.size(); i++) { 2794cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mAdded.get(i); 27950adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (f != null) { 27960adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (f.performContextItemSelected(item)) { 2797cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return true; 2798cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2799cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2800cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2801cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2802cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return false; 2803cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2804dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2805cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchOptionsMenuClosed(Menu menu) { 2806464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mAdded != null) { 2807cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<mAdded.size(); i++) { 2808cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mAdded.get(i); 28090adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (f != null) { 28100adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.performOptionsMenuClosed(menu); 2811cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2812cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2813cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2814cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2815461b48b4588ac21b97aa40553f04222c2c0344e7Chris Banes 2816cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public static int reverseTransit(int transit) { 2817cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int rev = 0; 2818cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn switch (transit) { 2819cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case FragmentTransaction.TRANSIT_FRAGMENT_OPEN: 2820cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn rev = FragmentTransaction.TRANSIT_FRAGMENT_CLOSE; 2821cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 2822cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case FragmentTransaction.TRANSIT_FRAGMENT_CLOSE: 2823cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn rev = FragmentTransaction.TRANSIT_FRAGMENT_OPEN; 2824cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 2825cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case FragmentTransaction.TRANSIT_FRAGMENT_FADE: 2826cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn rev = FragmentTransaction.TRANSIT_FRAGMENT_FADE; 2827cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 2828cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2829cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return rev; 2830dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2831cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2832dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 28339277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn public static final int ANIM_STYLE_OPEN_ENTER = 1; 28349277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn public static final int ANIM_STYLE_OPEN_EXIT = 2; 28359277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn public static final int ANIM_STYLE_CLOSE_ENTER = 3; 28369277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn public static final int ANIM_STYLE_CLOSE_EXIT = 4; 28379277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn public static final int ANIM_STYLE_FADE_ENTER = 5; 28389277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn public static final int ANIM_STYLE_FADE_EXIT = 6; 2839dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2840cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public static int transitToStyleIndex(int transit, boolean enter) { 2841cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int animAttr = -1; 2842cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn switch (transit) { 2843cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case FragmentTransaction.TRANSIT_FRAGMENT_OPEN: 28449277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn animAttr = enter ? ANIM_STYLE_OPEN_ENTER : ANIM_STYLE_OPEN_EXIT; 2845cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 2846cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case FragmentTransaction.TRANSIT_FRAGMENT_CLOSE: 28479277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn animAttr = enter ? ANIM_STYLE_CLOSE_ENTER : ANIM_STYLE_CLOSE_EXIT; 2848cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 2849cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case FragmentTransaction.TRANSIT_FRAGMENT_FADE: 28509277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn animAttr = enter ? ANIM_STYLE_FADE_ENTER : ANIM_STYLE_FADE_EXIT; 2851cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 2852cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2853cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return animAttr; 2854cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 28550f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 28560f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell @Override 2857bf0947be2ead9b3d8e5865bcd3d3652d02a2aa5aChris Banes public View onCreateView(View parent, String name, Context context, AttributeSet attrs) { 28580f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (!"fragment".equals(name)) { 28590f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell return null; 28600f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 28610f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 28620f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell String fname = attrs.getAttributeValue(null, "class"); 28630f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell TypedArray a = context.obtainStyledAttributes(attrs, FragmentTag.Fragment); 28640f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (fname == null) { 28650f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fname = a.getString(FragmentTag.Fragment_name); 28660f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 28670f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell int id = a.getResourceId(FragmentTag.Fragment_id, View.NO_ID); 28680f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell String tag = a.getString(FragmentTag.Fragment_tag); 28690f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell a.recycle(); 28700f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 2871d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy if (!Fragment.isSupportFragmentClass(mHost.getContext(), fname)) { 28720f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // Invalid support lib fragment; let the device's framework handle it. 28730f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // This will allow android.app.Fragments to do the right thing. 28740f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell return null; 28750f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 28760f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 28770f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell int containerId = parent != null ? parent.getId() : 0; 28780f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (containerId == View.NO_ID && id == View.NO_ID && tag == null) { 28790f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell throw new IllegalArgumentException(attrs.getPositionDescription() 28800f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell + ": Must specify unique android:id, android:tag, or have a parent with an id for " + fname); 28810f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 28820f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 28830f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // If we restored from a previous state, we may already have 28840f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // instantiated this fragment from the state and should use 28850f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // that instance instead of making a new one. 28860f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell Fragment fragment = id != View.NO_ID ? findFragmentById(id) : null; 28870f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (fragment == null && tag != null) { 28880f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment = findFragmentByTag(tag); 28890f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 28900f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (fragment == null && containerId != View.NO_ID) { 28910f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment = findFragmentById(containerId); 28920f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 28930f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 28940f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (FragmentManagerImpl.DEBUG) Log.v(TAG, "onCreateView: id=0x" 28950f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell + Integer.toHexString(id) + " fname=" + fname 28960f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell + " existing=" + fragment); 28970f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (fragment == null) { 28980f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment = Fragment.instantiate(context, fname); 28990f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mFromLayout = true; 29000f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mFragmentId = id != 0 ? id : containerId; 29010f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mContainerId = containerId; 29020f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mTag = tag; 29030f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mInLayout = true; 29040f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mFragmentManager = this; 29051b84066e4233b4b0c8a32fffc30f95b8cd20ced4Chris Banes fragment.mHost = mHost; 2906b979cb86fa389effb7cd79fa045550c10b7b4819Todd Kennedy fragment.onInflate(mHost.getContext(), attrs, fragment.mSavedFragmentState); 29070f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell addFragment(fragment, true); 29080f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 29090f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } else if (fragment.mInLayout) { 29100f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // A fragment already exists and it is not one we restored from 29110f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // previous state. 29120f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell throw new IllegalArgumentException(attrs.getPositionDescription() 29130f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell + ": Duplicate id 0x" + Integer.toHexString(id) 29140f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell + ", tag " + tag + ", or parent id 0x" + Integer.toHexString(containerId) 29150f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell + " with another fragment for " + fname); 29160f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } else { 29170f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // This fragment was retained from a previous instance; get it 29180f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // going now. 29190f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mInLayout = true; 2920e4148d65bbd62585c68c5782c2081bab6b303568Todd Kennedy fragment.mHost = mHost; 29210f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // If this fragment is newly instantiated (either right now, or 29220f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // from last saved state), then give it the attributes to 29230f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // initialize itself. 29240f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (!fragment.mRetaining) { 2925b979cb86fa389effb7cd79fa045550c10b7b4819Todd Kennedy fragment.onInflate(mHost.getContext(), attrs, fragment.mSavedFragmentState); 29260f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 29270f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 29280f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 29290f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // If we haven't finished entering the CREATED state ourselves yet, 29300f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // push the inflated child fragment along. 29310f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (mCurState < Fragment.CREATED && fragment.mFromLayout) { 29320f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell moveToState(fragment, Fragment.CREATED, 0, 0, false); 29330f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } else { 29340f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell moveToState(fragment); 29350f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 29360f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 29370f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (fragment.mView == null) { 29380f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell throw new IllegalStateException("Fragment " + fname 29390f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell + " did not create a view."); 29400f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 29410f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (id != 0) { 29420f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mView.setId(id); 29430f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 29440f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (fragment.mView.getTag() == null) { 29450f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mView.setTag(tag); 29460f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 29470f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell return fragment.mView; 29480f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 29490f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 2950bf0947be2ead9b3d8e5865bcd3d3652d02a2aa5aChris Banes LayoutInflaterFactory getLayoutInflaterFactory() { 29510f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell return this; 29520f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 29530f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 29540f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell static class FragmentTag { 29550f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell public static final int[] Fragment = { 29560f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 0x01010003, 0x010100d0, 0x010100d1 29570f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell }; 29580f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell public static final int Fragment_id = 1; 29590f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell public static final int Fragment_name = 0; 29600f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell public static final int Fragment_tag = 2; 29610f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 2962990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2963990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2964990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * An add or pop transaction to be scheduled for the UI thread. 2965990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2966990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount interface OpGenerator { 2967990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2968990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Generate transactions to add to {@code records} and whether or not the transaction is 2969990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * an add or pop to {@code isRecordPop}. 2970990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 2971990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * records and isRecordPop must be added equally so that each transaction in records 2972990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * matches the boolean for whether or not it is a pop in isRecordPop. 2973990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 2974990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param records A list to add transactions to. 2975990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param isRecordPop A list to add whether or not the transactions added to records is 2976990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * a pop transaction. 2977990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @return true if something was added or false otherwise. 2978990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2979990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean generateOps(ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop); 2980990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2981990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2982990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2983990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * A pop operation OpGenerator. This will be run on the UI thread and will generate the 2984990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * transactions that will be popped if anything can be popped. 2985990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2986990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private class PopBackStackState implements OpGenerator { 2987990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final String mName; 2988990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int mId; 2989990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int mFlags; 2990990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2991990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount PopBackStackState(String name, int id, int flags) { 2992990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mName = name; 2993990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mId = id; 2994990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mFlags = flags; 2995990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2996990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2997990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Override 2998990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public boolean generateOps(ArrayList<BackStackRecord> records, 2999990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Boolean> isRecordPop) { 3000990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return popBackStackState(records, isRecordPop, mName, mId, mFlags); 3001990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3002990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3003990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3004990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 3005990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * A listener for a postponed transaction. This waits until 3006990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@link Fragment#startPostponedEnterTransition()} is called or a transaction is started 3007990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * that interacts with this one, based on interactions with the fragment container. 3008990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 3009990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount static class StartEnterTransitionListener 3010990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount implements Fragment.OnStartEnterTransitionListener { 3011990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private final boolean mIsBack; 3012990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private final BackStackRecord mRecord; 3013990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private int mNumPostponed; 3014990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3015990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount StartEnterTransitionListener(BackStackRecord record, boolean isBack) { 3016990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mIsBack = isBack; 3017990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mRecord = record; 3018990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3019990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3020990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 3021990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Called from {@link Fragment#startPostponedEnterTransition()}, this decreases the 3022990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * number of Fragments that are postponed. This may cause the transaction to schedule 3023990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * to finish running and run transitions and animations. 3024990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 3025990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Override 3026990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void onStartEnterTransition() { 3027990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mNumPostponed--; 3028990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mNumPostponed != 0) { 3029990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return; 3030990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3031990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mRecord.mManager.scheduleCommit(); 3032990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3033990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3034990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 3035990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Called from {@link Fragment# 3036990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * setOnStartEnterTransitionListener(Fragment.OnStartEnterTransitionListener)}, this 3037990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * increases the number of fragments that are postponed as part of this transaction. 3038990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 3039990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Override 3040990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void startListening() { 3041990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mNumPostponed++; 3042990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3043990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3044990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 3045990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @return true if there are no more postponed fragments as part of the transaction. 3046990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 3047990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public boolean isReady() { 3048990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return mNumPostponed == 0; 3049990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3050990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3051990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 3052990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Completes the transaction and start the animations and transitions. This may skip 3053990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * the transitions if this is called before all fragments have called 3054990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@link Fragment#startPostponedEnterTransition()}. 3055990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 3056990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void completeTransaction() { 3057990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final boolean canceled; 3058990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount canceled = mNumPostponed > 0; 3059990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentManagerImpl manager = mRecord.mManager; 3060990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int numAdded = manager.mAdded.size(); 3061990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numAdded; i++) { 3062990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final Fragment fragment = manager.mAdded.get(i); 3063990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.setOnStartEnterTransitionListener(null); 3064990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (canceled && fragment.isPostponed()) { 3065990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.startPostponedEnterTransition(); 3066990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3067990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3068990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mRecord.mManager.completeExecute(mRecord, mIsBack, !canceled, true); 3069990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3070990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3071990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 3072990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Cancels this transaction instead of completing it. That means that the state isn't 3073990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * changed, so the pop results in no change to the state. 3074990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 3075990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void cancelTransaction() { 3076990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mRecord.mManager.completeExecute(mRecord, mIsBack, false, false); 3077990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3078990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3079cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn} 3080