FragmentManager.java revision 25806414c27ad7a9b194e01328b1315058d3d2ad
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 198e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikasimport static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP; 2077f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge 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; 340bb3f19c91311de0b6619c7728a7bcc1f6863132George Mountimport android.support.v4.util.ArraySet; 35cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.support.v4.util.DebugUtils; 36cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.support.v4.util.LogWriter; 37267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powellimport android.support.v4.util.Pair; 385e63ab9505a3a4d11374cbbec418c1aba921409dChris Banesimport android.support.v4.view.ViewCompat; 390f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powellimport android.util.AttributeSet; 40cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.util.Log; 41cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.util.SparseArray; 42267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powellimport android.view.LayoutInflater; 43990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.view.Menu; 44990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.view.MenuInflater; 45990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.view.MenuItem; 46990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.view.View; 47990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.view.ViewGroup; 489277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackbornimport android.view.animation.AccelerateInterpolator; 499277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackbornimport android.view.animation.AlphaAnimation; 50cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.view.animation.Animation; 51990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.view.animation.Animation.AnimationListener; 529277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackbornimport android.view.animation.AnimationSet; 53cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.view.animation.AnimationUtils; 549277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackbornimport android.view.animation.DecelerateInterpolator; 559277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackbornimport android.view.animation.Interpolator; 569277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackbornimport android.view.animation.ScaleAnimation; 57cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 58cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport java.io.FileDescriptor; 59cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport java.io.PrintWriter; 60d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liuimport java.lang.reflect.Field; 61cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport java.util.ArrayList; 62cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport java.util.Arrays; 6343db3168ca4a4d309f059363054ba60bc22a9ef3George Mountimport java.util.Collection; 6496221034e4a23a2abb83f772a0281bb197ac5ac0George Mountimport java.util.Collections; 653a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brownimport java.util.List; 66267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powellimport java.util.concurrent.CopyOnWriteArrayList; 67267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 68cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn/** 69cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Static library support version of the framework's {@link android.app.FragmentManager}. 70cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Used to write apps that run on platforms prior to Android 3.0. When running 71cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * on Android 3.0 or above, this implementation is still used; it does not try 729dcd2e58138ca4eb4b18f80b50e8979329e859d6Scott Main * to switch to the framework's implementation. See the framework {@link FragmentManager} 73cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * documentation for a class overview. 749dcd2e58138ca4eb4b18f80b50e8979329e859d6Scott Main * 759dcd2e58138ca4eb4b18f80b50e8979329e859d6Scott Main * <p>Your activity must derive from {@link FragmentActivity} to use this. From such an activity, 769dcd2e58138ca4eb4b18f80b50e8979329e859d6Scott Main * you can acquire the {@link FragmentManager} by calling 779dcd2e58138ca4eb4b18f80b50e8979329e859d6Scott Main * {@link FragmentActivity#getSupportFragmentManager}. 78cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 79cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornpublic abstract class FragmentManager { 80cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 81cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Representation of an entry on the fragment back stack, as created 82cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * with {@link FragmentTransaction#addToBackStack(String) 83cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * FragmentTransaction.addToBackStack()}. Entries can later be 84cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * retrieved with {@link FragmentManager#getBackStackEntryAt(int) 85fd28b81e0501d11989a8ad095c1a54619000df19Aurimas Liutikas * FragmentManager.getBackStackEntryAt()}. 86cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * 87cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * <p>Note that you should never hold on to a BackStackEntry object; 88cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * the identifier as returned by {@link #getId} is the only thing that 89cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * will be persisted across activity instances. 90cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 91cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public interface BackStackEntry { 92cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 93cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Return the unique identifier for the entry. This is the only 94cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * representation of the entry that will persist across activity 95cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * instances. 96cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 97cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public int getId(); 98cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 99cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 1002a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn * Get the name that was supplied to 1012a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn * {@link FragmentTransaction#addToBackStack(String) 1022a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn * FragmentTransaction.addToBackStack(String)} when creating this entry. 1032a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn */ 1042a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn public String getName(); 1052a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn 1062a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn /** 107cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Return the full bread crumb title resource identifier for the entry, 108cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * or 0 if it does not have one. 109cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 110a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye @StringRes 111cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public int getBreadCrumbTitleRes(); 112cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 113cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 114cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Return the short bread crumb title resource identifier for the entry, 115cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * or 0 if it does not have one. 116cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 117a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye @StringRes 118cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public int getBreadCrumbShortTitleRes(); 119cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 120cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 121cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Return the full bread crumb title for the entry, or null if it 122cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * does not have one. 123cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 124cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public CharSequence getBreadCrumbTitle(); 125cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 126cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 127cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Return the short bread crumb title for the entry, or null if it 128cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * does not have one. 129cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 130cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public CharSequence getBreadCrumbShortTitle(); 131cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 132cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 133cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 134cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Interface to watch for changes to the back stack. 135cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 136cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public interface OnBackStackChangedListener { 137cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 138cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Called whenever the contents of the back stack change. 139cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 140cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void onBackStackChanged(); 141cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 142cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 143cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 144cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Start a series of edit operations on the Fragments associated with 145cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * this FragmentManager. 146dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas * 147cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * <p>Note: A fragment transaction can only be created/committed prior 148cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * to an activity saving its state. If you try to commit a transaction 149cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * after {@link FragmentActivity#onSaveInstanceState FragmentActivity.onSaveInstanceState()} 150cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * (and prior to a following {@link FragmentActivity#onStart FragmentActivity.onStart} 151cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * or {@link FragmentActivity#onResume FragmentActivity.onResume()}, you will get an error. 152cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * This is because the framework takes care of saving your current fragments 153cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * in the state, and if changes are made after the state is saved then they 154cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * will be lost.</p> 155cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 156cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract FragmentTransaction beginTransaction(); 157cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 158d805095048f6be52cddbd572ee343c4639ba8187Alan Viverette /** 159d805095048f6be52cddbd572ee343c4639ba8187Alan Viverette * @hide -- remove once prebuilts are in. 160d805095048f6be52cddbd572ee343c4639ba8187Alan Viverette * @deprecated 161d805095048f6be52cddbd572ee343c4639ba8187Alan Viverette */ 1628e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas @RestrictTo(LIBRARY_GROUP) 163cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Deprecated 164cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public FragmentTransaction openTransaction() { 165cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return beginTransaction(); 166cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 167dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 168cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 169cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * After a {@link FragmentTransaction} is committed with 170cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * {@link FragmentTransaction#commit FragmentTransaction.commit()}, it 171cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * is scheduled to be executed asynchronously on the process's main thread. 172cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * If you want to immediately executing any such pending operations, you 173cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * can call this function (only from the main thread) to do so. Note that 174cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * all callbacks and other related behavior will be done from within this 175cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * call, so be careful about where this is called from. 176cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * 1771500716b2257e9f442606fe5bd992ab4e0198dcbAdam Powell * <p>If you are committing a single transaction that does not modify the 1781500716b2257e9f442606fe5bd992ab4e0198dcbAdam Powell * fragment back stack, strongly consider using 1791500716b2257e9f442606fe5bd992ab4e0198dcbAdam Powell * {@link FragmentTransaction#commitNow()} instead. This can help avoid 1801500716b2257e9f442606fe5bd992ab4e0198dcbAdam Powell * unwanted side effects when other code in your app has pending committed 1811500716b2257e9f442606fe5bd992ab4e0198dcbAdam Powell * transactions that expect different timing.</p> 182990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * <p> 183990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * This also forces the start of any postponed Transactions where 184990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@link Fragment#postponeEnterTransition()} has been called. 1851500716b2257e9f442606fe5bd992ab4e0198dcbAdam Powell * 186cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @return Returns true if there were any pending transactions to be 187cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * executed. 188cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 189cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract boolean executePendingTransactions(); 190cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 191cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 192cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Finds a fragment that was identified by the given id either when inflated 193cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * from XML or as the container ID when added in a transaction. This first 194cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * searches through fragments that are currently added to the manager's 195cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * activity; if no such fragment is found, then all fragments currently 196cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * on the back stack associated with this ID are searched. 197cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @return The fragment if found or null otherwise. 198cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 199a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye public abstract Fragment findFragmentById(@IdRes int id); 200cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 201cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 202cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Finds a fragment that was identified by the given tag either when inflated 203cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * from XML or as supplied when added in a transaction. This first 204cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * searches through fragments that are currently added to the manager's 205cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * activity; if no such fragment is found, then all fragments currently 206cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * on the back stack are searched. 207cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @return The fragment if found or null otherwise. 208cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 209cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract Fragment findFragmentByTag(String tag); 210cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 211cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 212cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Flag for {@link #popBackStack(String, int)} 213cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * and {@link #popBackStack(int, int)}: If set, and the name or ID of 214cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * a back stack entry has been supplied, then all matching entries will 215cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * be consumed until one that doesn't match is found or the bottom of 216cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * the stack is reached. Otherwise, all entries up to but not including that entry 217cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * will be removed. 218cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 219cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public static final int POP_BACK_STACK_INCLUSIVE = 1<<0; 220cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 221cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 222cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Pop the top state off the back stack. Returns true if there was one 223cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * to pop, else false. This function is asynchronous -- it enqueues the 224cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * request to pop, but the action will not be performed until the application 225cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * returns to its event loop. 226cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 227cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract void popBackStack(); 228cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 229cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 230cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Like {@link #popBackStack()}, but performs the operation immediately 231cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * inside of the call. This is like calling {@link #executePendingTransactions()} 232990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * afterwards without forcing the start of postponed Transactions. 233cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @return Returns true if there was something popped, else false. 234cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 235cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract boolean popBackStackImmediate(); 236cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 237cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 238cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Pop the last fragment transition from the manager's fragment 239cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * back stack. If there is nothing to pop, false is returned. 240cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * This function is asynchronous -- it enqueues the 241cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * request to pop, but the action will not be performed until the application 242cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * returns to its event loop. 243dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas * 244cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param name If non-null, this is the name of a previous back state 245cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * to look for; if found, all states up to that state will be popped. The 246cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * {@link #POP_BACK_STACK_INCLUSIVE} flag can be used to control whether 247cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * the named state itself is popped. If null, only the top state is popped. 248cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param flags Either 0 or {@link #POP_BACK_STACK_INCLUSIVE}. 249cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 250cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract void popBackStack(String name, int flags); 251cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 252cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 253cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Like {@link #popBackStack(String, int)}, but performs the operation immediately 254cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * inside of the call. This is like calling {@link #executePendingTransactions()} 255990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * afterwards without forcing the start of postponed Transactions. 256cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @return Returns true if there was something popped, else false. 257cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 258cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract boolean popBackStackImmediate(String name, int flags); 259cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 260cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 261cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Pop all back stack states up to the one with the given identifier. 262cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * This function is asynchronous -- it enqueues the 263cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * request to pop, but the action will not be performed until the application 264cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * returns to its event loop. 265dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas * 266cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param id Identifier of the stated to be popped. If no identifier exists, 267cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * false is returned. 268cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * The identifier is the number returned by 269cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * {@link FragmentTransaction#commit() FragmentTransaction.commit()}. The 270cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * {@link #POP_BACK_STACK_INCLUSIVE} flag can be used to control whether 271cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * the named state itself is popped. 272cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param flags Either 0 or {@link #POP_BACK_STACK_INCLUSIVE}. 273cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 274cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract void popBackStack(int id, int flags); 275cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 276cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 277cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Like {@link #popBackStack(int, int)}, but performs the operation immediately 278cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * inside of the call. This is like calling {@link #executePendingTransactions()} 279990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * afterwards without forcing the start of postponed Transactions. 280cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @return Returns true if there was something popped, else false. 281cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 282cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract boolean popBackStackImmediate(int id, int flags); 283cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 284cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 285cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Return the number of entries currently in the back stack. 286cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 287cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract int getBackStackEntryCount(); 288cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 289cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 290cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Return the BackStackEntry at index <var>index</var> in the back stack; 291cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * entries start index 0 being the bottom of the stack. 292cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 293cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract BackStackEntry getBackStackEntryAt(int index); 294cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 295cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 296cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Add a new listener for changes to the fragment back stack. 297cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 298cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract void addOnBackStackChangedListener(OnBackStackChangedListener listener); 299cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 300cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 301cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Remove a listener that was previously added with 302cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * {@link #addOnBackStackChangedListener(OnBackStackChangedListener)}. 303cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 304cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract void removeOnBackStackChangedListener(OnBackStackChangedListener listener); 305cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 306cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 307cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Put a reference to a fragment in a Bundle. This Bundle can be 308cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * persisted as saved state, and when later restoring 309cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * {@link #getFragment(Bundle, String)} will return the current 310cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * instance of the same fragment. 311cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * 312cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param bundle The bundle in which to put the fragment reference. 313cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param key The name of the entry in the bundle. 314cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param fragment The Fragment whose reference is to be stored. 315cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 316cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract void putFragment(Bundle bundle, String key, Fragment fragment); 317cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 318cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 319cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Retrieve the current Fragment instance for a reference previously 320cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * placed with {@link #putFragment(Bundle, String, Fragment)}. 321cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * 322cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param bundle The bundle from which to retrieve the fragment reference. 323cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param key The name of the entry in the bundle. 324cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @return Returns the current Fragment instance that is associated with 325cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * the given reference. 326cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 327cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract Fragment getFragment(Bundle bundle, String key); 328cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 329cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 33043db3168ca4a4d309f059363054ba60bc22a9ef3George Mount * Get a collection of all fragments that are currently added to the FragmentManager. 33196221034e4a23a2abb83f772a0281bb197ac5ac0George Mount * This may include those that are hidden as well as those that are shown. 33296221034e4a23a2abb83f772a0281bb197ac5ac0George Mount * This will not include any fragments only in the back stack, or fragments that 33396221034e4a23a2abb83f772a0281bb197ac5ac0George Mount * are detached or removed. 3343a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown * 33543db3168ca4a4d309f059363054ba60bc22a9ef3George Mount * @return A collection of all fragments that are added to the FragmentManager. 3363a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown */ 33743db3168ca4a4d309f059363054ba60bc22a9ef3George Mount public abstract Collection<Fragment> getFragments(); 3383a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown 3393a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown /** 3405c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * Save the current instance state of the given Fragment. This can be 3415c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * used later when creating a new instance of the Fragment and adding 3425c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * it to the fragment manager, to have it create itself to match the 3435c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * current state returned here. Note that there are limits on how 3445c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * this can be used: 3455c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * 3465c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * <ul> 3475c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * <li>The Fragment must currently be attached to the FragmentManager. 3485c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * <li>A new Fragment created using this saved state must be the same class 3495c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * type as the Fragment it was created from. 3505c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * <li>The saved state can not contain dependencies on other fragments -- 3515c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * that is it can't use {@link #putFragment(Bundle, String, Fragment)} to 3525c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * store a fragment reference because that reference may not be valid when 3535c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * this saved state is later used. Likewise the Fragment's target and 3545c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * result code are not included in this state. 3555c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * </ul> 3565c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * 3575c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * @param f The Fragment whose state is to be saved. 3585c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * @return The generated state. This will be null if there was no 3595c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * interesting state created by the fragment. 3605c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn */ 3615c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn public abstract Fragment.SavedState saveFragmentInstanceState(Fragment f); 3625c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn 3635c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn /** 36401df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler * Returns true if the final {@link android.app.Activity#onDestroy() Activity.onDestroy()} 36501df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler * call has been made on the FragmentManager's Activity, so this instance is now dead. 36601df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler */ 36701df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler public abstract boolean isDestroyed(); 36801df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler 36901df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler /** 370267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Registers a {@link FragmentLifecycleCallbacks} to listen to fragment lifecycle events 371267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * happening in this FragmentManager. All registered callbacks will be automatically 372267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * unregistered when this FragmentManager is destroyed. 373267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 374267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param cb Callbacks to register 375267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param recursive true to automatically register this callback for all child FragmentManagers 376267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 377267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell public abstract void registerFragmentLifecycleCallbacks(FragmentLifecycleCallbacks cb, 378267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell boolean recursive); 379267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 380267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 381267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Unregisters a previously registered {@link FragmentLifecycleCallbacks}. If the callback 382267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * was not previously registered this call has no effect. All registered callbacks will be 383267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * automatically unregistered when this FragmentManager is destroyed. 384267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 385267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param cb Callbacks to unregister 386267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 387267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell public abstract void unregisterFragmentLifecycleCallbacks(FragmentLifecycleCallbacks cb); 388267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 389267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 390418738949305a8a0e30eba92c125c650048f9c50Adam Powell * Return the currently active primary navigation fragment for this FragmentManager. 391418738949305a8a0e30eba92c125c650048f9c50Adam Powell * 392418738949305a8a0e30eba92c125c650048f9c50Adam Powell * <p>The primary navigation fragment's 393418738949305a8a0e30eba92c125c650048f9c50Adam Powell * {@link Fragment#getChildFragmentManager() child FragmentManager} will be called first 394418738949305a8a0e30eba92c125c650048f9c50Adam Powell * to process delegated navigation actions such as {@link #popBackStack()} if no ID 395418738949305a8a0e30eba92c125c650048f9c50Adam Powell * or transaction name is provided to pop to.</p> 396418738949305a8a0e30eba92c125c650048f9c50Adam Powell * 397418738949305a8a0e30eba92c125c650048f9c50Adam Powell * @return the fragment designated as the primary navigation fragment 398418738949305a8a0e30eba92c125c650048f9c50Adam Powell */ 399418738949305a8a0e30eba92c125c650048f9c50Adam Powell public abstract Fragment getPrimaryNavigationFragment(); 400418738949305a8a0e30eba92c125c650048f9c50Adam Powell 401418738949305a8a0e30eba92c125c650048f9c50Adam Powell /** 402cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Print the FragmentManager's state into the given stream. 403cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * 404cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param prefix Text to print at the front of each line. 405cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param fd The raw file descriptor that the dump is being sent to. 406cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param writer A PrintWriter to which the dump is to be set. 407cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param args Additional arguments to the dump request. 408cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 409cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args); 410cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 411cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 412cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Control whether the framework's internal fragment manager debugging 413cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * logs are turned on. If enabled, you will see output in logcat as 414cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * the framework performs fragment operations. 415cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 416cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public static void enableDebugLogging(boolean enabled) { 417cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentManagerImpl.DEBUG = enabled; 418cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 419267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 420267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 42147844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount * Returns {@code true} if the FragmentManager's state has already been saved 42247844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount * by its host. Any operations that would change saved state should not be performed 42347844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount * if this method returns true. For example, any popBackStack() method, such as 42447844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount * {@link #popBackStackImmediate()} or any FragmentTransaction using 42547844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount * {@link FragmentTransaction#commit()} instead of 42647844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount * {@link FragmentTransaction#commitAllowingStateLoss()} will change 42747844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount * the state and will result in an error. 42847844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount * 42947844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount * @return true if this FragmentManager's state has already been saved by its host 43047844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount */ 43147844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount public abstract boolean isStateSaved(); 43247844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount 43347844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount /** 434267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Callback interface for listening to fragment state changes that happen 435267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * within a given FragmentManager. 436267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 4371b5b6c012765919f50bfb64dcf494a2d8cfcfbb1Adam Powell public abstract static class FragmentLifecycleCallbacks { 438267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 439267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Called right before the fragment's {@link Fragment#onAttach(Context)} method is called. 440267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * This is a good time to inject any required dependencies for the fragment before any of 441267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * the fragment's lifecycle methods are invoked. 442267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 443267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param fm Host FragmentManager 444267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param f Fragment changing state 445267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param context Context that the Fragment is being attached to 446267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 447267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell public void onFragmentPreAttached(FragmentManager fm, Fragment f, Context context) {} 448267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 449267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 450267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Called after the fragment has been attached to its host. Its host will have had 451267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * <code>onAttachFragment</code> called before this call happens. 452267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 453267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param fm Host FragmentManager 454267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param f Fragment changing state 455267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param context Context that the Fragment was attached to 456267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 457267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell public void onFragmentAttached(FragmentManager fm, Fragment f, Context context) {} 458267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 459267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 460267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Called after the fragment has returned from the FragmentManager's call to 461267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * {@link Fragment#onCreate(Bundle)}. This will only happen once for any given 462267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * fragment instance, though the fragment may be attached and detached multiple times. 463267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 464267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param fm Host FragmentManager 465267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param f Fragment changing state 466267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param savedInstanceState Saved instance bundle from a previous instance 467267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 468267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell public void onFragmentCreated(FragmentManager fm, Fragment f, Bundle savedInstanceState) {} 469267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 470267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 471267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Called after the fragment has returned from the FragmentManager's call to 472267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * {@link Fragment#onActivityCreated(Bundle)}. This will only happen once for any given 473267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * fragment instance, though the fragment may be attached and detached multiple times. 474267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 475267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param fm Host FragmentManager 476267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param f Fragment changing state 477267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param savedInstanceState Saved instance bundle from a previous instance 478267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 479267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell public void onFragmentActivityCreated(FragmentManager fm, Fragment f, 480267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell Bundle savedInstanceState) {} 481267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 482267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 483267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Called after the fragment has returned a non-null view from the FragmentManager's 484267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * request to {@link Fragment#onCreateView(LayoutInflater, ViewGroup, Bundle)}. 485267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 486267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param fm Host FragmentManager 487267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param f Fragment that created and owns the view 488267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param v View returned by the fragment 489267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param savedInstanceState Saved instance bundle from a previous instance 490267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 491267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell public void onFragmentViewCreated(FragmentManager fm, Fragment f, View v, 492267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell Bundle savedInstanceState) {} 493267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 494267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 495267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Called after the fragment has returned from the FragmentManager's call to 496267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * {@link Fragment#onStart()}. 497267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 498267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param fm Host FragmentManager 499267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param f Fragment changing state 500267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 501267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell public void onFragmentStarted(FragmentManager fm, Fragment f) {} 502267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 503267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 504267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Called after the fragment has returned from the FragmentManager's call to 505267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * {@link Fragment#onResume()}. 506267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 507267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param fm Host FragmentManager 508267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param f Fragment changing state 509267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 510267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell public void onFragmentResumed(FragmentManager fm, Fragment f) {} 511267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 512267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 513267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Called after the fragment has returned from the FragmentManager's call to 514267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * {@link Fragment#onPause()}. 515267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 516267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param fm Host FragmentManager 517267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param f Fragment changing state 518267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 519267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell public void onFragmentPaused(FragmentManager fm, Fragment f) {} 520267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 521267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 522267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Called after the fragment has returned from the FragmentManager's call to 523267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * {@link Fragment#onStop()}. 524267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 525267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param fm Host FragmentManager 526267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param f Fragment changing state 527267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 528267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell public void onFragmentStopped(FragmentManager fm, Fragment f) {} 529267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 530267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 531267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Called after the fragment has returned from the FragmentManager's call to 532267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * {@link Fragment#onSaveInstanceState(Bundle)}. 533267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 534267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param fm Host FragmentManager 535267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param f Fragment changing state 536267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param outState Saved state bundle for the fragment 537267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 538267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell public void onFragmentSaveInstanceState(FragmentManager fm, Fragment f, Bundle outState) {} 539267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 540267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 541267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Called after the fragment has returned from the FragmentManager's call to 542267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * {@link Fragment#onDestroyView()}. 543267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 544267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param fm Host FragmentManager 545267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param f Fragment changing state 546267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 547267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell public void onFragmentViewDestroyed(FragmentManager fm, Fragment f) {} 548267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 549267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 550267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Called after the fragment has returned from the FragmentManager's call to 551267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * {@link Fragment#onDestroy()}. 552267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 553267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param fm Host FragmentManager 554267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param f Fragment changing state 555267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 556267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell public void onFragmentDestroyed(FragmentManager fm, Fragment f) {} 557267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 558267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 559267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Called after the fragment has returned from the FragmentManager's call to 560267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * {@link Fragment#onDetach()}. 561267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 562267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param fm Host FragmentManager 563267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param f Fragment changing state 564267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 565267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell public void onFragmentDetached(FragmentManager fm, Fragment f) {} 566267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 567cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn} 568cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 569cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornfinal class FragmentManagerState implements Parcelable { 570cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentState[] mActive; 571cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int[] mAdded; 572cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn BackStackState[] mBackStack; 573418738949305a8a0e30eba92c125c650048f9c50Adam Powell int mPrimaryNavActiveIndex = -1; 57490b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount int mNextFragmentIndex; 575dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 576cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public FragmentManagerState() { 577cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 578dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 579cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public FragmentManagerState(Parcel in) { 580cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mActive = in.createTypedArray(FragmentState.CREATOR); 581cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAdded = in.createIntArray(); 582cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStack = in.createTypedArray(BackStackState.CREATOR); 583418738949305a8a0e30eba92c125c650048f9c50Adam Powell mPrimaryNavActiveIndex = in.readInt(); 58490b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount mNextFragmentIndex = in.readInt(); 585cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 58690ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas 58790ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas @Override 588cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public int describeContents() { 589cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return 0; 590cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 591cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 59290ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas @Override 593cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void writeToParcel(Parcel dest, int flags) { 594cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn dest.writeTypedArray(mActive, flags); 595cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn dest.writeIntArray(mAdded); 596cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn dest.writeTypedArray(mBackStack, flags); 597418738949305a8a0e30eba92c125c650048f9c50Adam Powell dest.writeInt(mPrimaryNavActiveIndex); 59890b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount dest.writeInt(mNextFragmentIndex); 599cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 600dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 601cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public static final Parcelable.Creator<FragmentManagerState> CREATOR 602cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn = new Parcelable.Creator<FragmentManagerState>() { 60390ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas @Override 604cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public FragmentManagerState createFromParcel(Parcel in) { 605cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return new FragmentManagerState(in); 606cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 60790ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas 60890ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas @Override 609cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public FragmentManagerState[] newArray(int size) { 610cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return new FragmentManagerState[size]; 611cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 612cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn }; 613cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn} 614cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 615cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn/** 616cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Container for fragments associated with an activity. 617cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 6184bf8c3d1aeb944a993c946db770604b55f981341Aurimas Liutikasfinal class FragmentManagerImpl extends FragmentManager implements LayoutInflater.Factory2 { 619cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn static boolean DEBUG = false; 620cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn static final String TAG = "FragmentManager"; 621dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 622cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn static final String TARGET_REQUEST_CODE_STATE_TAG = "android:target_req_state"; 623cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn static final String TARGET_STATE_TAG = "android:target_state"; 624cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn static final String VIEW_STATE_TAG = "android:view_state"; 62579398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell static final String USER_VISIBLE_HINT_TAG = "android:user_visible_hint"; 626cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 62703526560f132021f8fd7290259762ab362d4d567Doris Liu static class AnimateOnHWLayerIfNeededListener implements AnimationListener { 628c9a859537b0871f84afeeb706a5b425fe3f2b4ddAurimas Liutikas private AnimationListener mOriginalListener; 6291802bf381380809e224c72008a400715e2e375b4Adam Powell private boolean mShouldRunOnHWLayer; 630dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas View mView; 6311802bf381380809e224c72008a400715e2e375b4Adam Powell 63203526560f132021f8fd7290259762ab362d4d567Doris Liu public AnimateOnHWLayerIfNeededListener(final View v, Animation anim) { 63303526560f132021f8fd7290259762ab362d4d567Doris Liu if (v == null || anim == null) { 63403526560f132021f8fd7290259762ab362d4d567Doris Liu return; 63503526560f132021f8fd7290259762ab362d4d567Doris Liu } 63603526560f132021f8fd7290259762ab362d4d567Doris Liu mView = v; 63703526560f132021f8fd7290259762ab362d4d567Doris Liu } 63803526560f132021f8fd7290259762ab362d4d567Doris Liu 639d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu public AnimateOnHWLayerIfNeededListener(final View v, Animation anim, 640d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu AnimationListener listener) { 641d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu if (v == null || anim == null) { 642d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu return; 643d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu } 644c9a859537b0871f84afeeb706a5b425fe3f2b4ddAurimas Liutikas mOriginalListener = listener; 645d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu mView = v; 6461802bf381380809e224c72008a400715e2e375b4Adam Powell mShouldRunOnHWLayer = true; 647d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu } 648d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu 64903526560f132021f8fd7290259762ab362d4d567Doris Liu @Override 65003526560f132021f8fd7290259762ab362d4d567Doris Liu @CallSuper 65103526560f132021f8fd7290259762ab362d4d567Doris Liu public void onAnimationStart(Animation animation) { 652c9a859537b0871f84afeeb706a5b425fe3f2b4ddAurimas Liutikas if (mOriginalListener != null) { 653c9a859537b0871f84afeeb706a5b425fe3f2b4ddAurimas Liutikas mOriginalListener.onAnimationStart(animation); 65403526560f132021f8fd7290259762ab362d4d567Doris Liu } 65503526560f132021f8fd7290259762ab362d4d567Doris Liu } 65603526560f132021f8fd7290259762ab362d4d567Doris Liu 65703526560f132021f8fd7290259762ab362d4d567Doris Liu @Override 65803526560f132021f8fd7290259762ab362d4d567Doris Liu @CallSuper 65903526560f132021f8fd7290259762ab362d4d567Doris Liu public void onAnimationEnd(Animation animation) { 660d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu if (mView != null && mShouldRunOnHWLayer) { 6611802bf381380809e224c72008a400715e2e375b4Adam Powell // If we're attached to a window, assume we're in the normal performTraversals 6621802bf381380809e224c72008a400715e2e375b4Adam Powell // drawing path for Animations running. It's not safe to change the layer type 6631802bf381380809e224c72008a400715e2e375b4Adam Powell // during drawing, so post it to the View to run later. If we're not attached 6641802bf381380809e224c72008a400715e2e375b4Adam Powell // or we're running on N and above, post it to the view. If we're not on N and 6651802bf381380809e224c72008a400715e2e375b4Adam Powell // not attached, do it right now since existing platform versions don't run the 6661802bf381380809e224c72008a400715e2e375b4Adam Powell // hwui renderer for detached views off the UI thread making changing layer type 6671802bf381380809e224c72008a400715e2e375b4Adam Powell // safe, but posting may not be. 6681802bf381380809e224c72008a400715e2e375b4Adam Powell // Prior to N posting to a detached view from a non-Looper thread could cause 6691802bf381380809e224c72008a400715e2e375b4Adam Powell // leaks, since the thread-local run queue on a non-Looper thread would never 6701802bf381380809e224c72008a400715e2e375b4Adam Powell // be flushed. 6714867e99525d200f9aacf7508ee047054396a4870Aurimas Liutikas if (ViewCompat.isAttachedToWindow(mView) || Build.VERSION.SDK_INT >= 24) { 6721802bf381380809e224c72008a400715e2e375b4Adam Powell mView.post(new Runnable() { 6731802bf381380809e224c72008a400715e2e375b4Adam Powell @Override 6741802bf381380809e224c72008a400715e2e375b4Adam Powell public void run() { 675fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas mView.setLayerType(View.LAYER_TYPE_NONE, null); 6761802bf381380809e224c72008a400715e2e375b4Adam Powell } 6771802bf381380809e224c72008a400715e2e375b4Adam Powell }); 6781802bf381380809e224c72008a400715e2e375b4Adam Powell } else { 679fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas mView.setLayerType(View.LAYER_TYPE_NONE, null); 6801802bf381380809e224c72008a400715e2e375b4Adam Powell } 68103526560f132021f8fd7290259762ab362d4d567Doris Liu } 682c9a859537b0871f84afeeb706a5b425fe3f2b4ddAurimas Liutikas if (mOriginalListener != null) { 683c9a859537b0871f84afeeb706a5b425fe3f2b4ddAurimas Liutikas mOriginalListener.onAnimationEnd(animation); 684d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu } 68503526560f132021f8fd7290259762ab362d4d567Doris Liu } 68603526560f132021f8fd7290259762ab362d4d567Doris Liu 68703526560f132021f8fd7290259762ab362d4d567Doris Liu @Override 68803526560f132021f8fd7290259762ab362d4d567Doris Liu public void onAnimationRepeat(Animation animation) { 689c9a859537b0871f84afeeb706a5b425fe3f2b4ddAurimas Liutikas if (mOriginalListener != null) { 690c9a859537b0871f84afeeb706a5b425fe3f2b4ddAurimas Liutikas mOriginalListener.onAnimationRepeat(animation); 691d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu } 69203526560f132021f8fd7290259762ab362d4d567Doris Liu } 69303526560f132021f8fd7290259762ab362d4d567Doris Liu } 69403526560f132021f8fd7290259762ab362d4d567Doris Liu 695990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<OpGenerator> mPendingActions; 696cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn boolean mExecutingActions; 697dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 69890b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount int mNextFragmentIndex = 0; 69990b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount 700cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ArrayList<Fragment> mAdded; 70190b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount SparseArray<Fragment> mActive; 702cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ArrayList<BackStackRecord> mBackStack; 703cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ArrayList<Fragment> mCreatedMenus; 704dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 705cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Must be accessed while locked. 706cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ArrayList<BackStackRecord> mBackStackIndices; 707cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ArrayList<Integer> mAvailBackStackIndices; 708cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 709cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ArrayList<OnBackStackChangedListener> mBackStackChangeListeners; 710267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell private CopyOnWriteArrayList<Pair<FragmentLifecycleCallbacks, Boolean>> mLifecycleCallbacks; 711cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 712cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int mCurState = Fragment.INITIALIZING; 7138491eb62f621cd5de4b4caed839be09c77011f53Todd Kennedy FragmentHostCallback mHost; 7140adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn FragmentContainer mContainer; 7150adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn Fragment mParent; 716418738949305a8a0e30eba92c125c650048f9c50Adam Powell Fragment mPrimaryNav; 717d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu 718d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu static Field sAnimationListenerField = null; 719dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 720cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn boolean mNeedMenuInvalidate; 721cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn boolean mStateSaved; 722cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn boolean mDestroyed; 723cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn String mNoTransactionsBecause; 72479398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell boolean mHavePendingDeferredStart; 725dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 726990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Temporary vars for optimizing execution of BackStackRecords: 727990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<BackStackRecord> mTmpRecords; 728990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Boolean> mTmpIsPop; 729990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Fragment> mTmpAddedFragments; 730990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 731cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Temporary vars for state save and restore. 732cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Bundle mStateBundle = null; 733cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn SparseArray<Parcelable> mStateArray = null; 734dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 735990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Postponed transactions. 736990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<StartEnterTransitionListener> mPostponedTransactions; 737990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 73825806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount // Saved FragmentManagerNonConfig during saveAllState() and cleared in noteStateNotSaved() 73925806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount FragmentManagerNonConfig mSavedNonConfig; 74025806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount 741cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Runnable mExecCommit = new Runnable() { 742cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 743cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void run() { 744cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn execPendingActions(); 745cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 746cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn }; 747cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 74803526560f132021f8fd7290259762ab362d4d567Doris Liu static boolean modifiesAlpha(Animation anim) { 74903526560f132021f8fd7290259762ab362d4d567Doris Liu if (anim instanceof AlphaAnimation) { 75003526560f132021f8fd7290259762ab362d4d567Doris Liu return true; 75103526560f132021f8fd7290259762ab362d4d567Doris Liu } else if (anim instanceof AnimationSet) { 75203526560f132021f8fd7290259762ab362d4d567Doris Liu List<Animation> anims = ((AnimationSet) anim).getAnimations(); 75303526560f132021f8fd7290259762ab362d4d567Doris Liu for (int i = 0; i < anims.size(); i++) { 75403526560f132021f8fd7290259762ab362d4d567Doris Liu if (anims.get(i) instanceof AlphaAnimation) { 75503526560f132021f8fd7290259762ab362d4d567Doris Liu return true; 75603526560f132021f8fd7290259762ab362d4d567Doris Liu } 75703526560f132021f8fd7290259762ab362d4d567Doris Liu } 75803526560f132021f8fd7290259762ab362d4d567Doris Liu } 75903526560f132021f8fd7290259762ab362d4d567Doris Liu return false; 76003526560f132021f8fd7290259762ab362d4d567Doris Liu } 76103526560f132021f8fd7290259762ab362d4d567Doris Liu 76203526560f132021f8fd7290259762ab362d4d567Doris Liu static boolean shouldRunOnHWLayer(View v, Animation anim) { 763b8d65fef161c7cd4bb06dc97685cf3fb3d6c3e1aChris Banes return Build.VERSION.SDK_INT >= 19 764fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas && v.getLayerType() == View.LAYER_TYPE_NONE 76503526560f132021f8fd7290259762ab362d4d567Doris Liu && ViewCompat.hasOverlappingRendering(v) 76603526560f132021f8fd7290259762ab362d4d567Doris Liu && modifiesAlpha(anim); 76703526560f132021f8fd7290259762ab362d4d567Doris Liu } 76803526560f132021f8fd7290259762ab362d4d567Doris Liu 76913fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn private void throwException(RuntimeException ex) { 77013fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn Log.e(TAG, ex.getMessage()); 771ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn Log.e(TAG, "Activity state:"); 77213fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn LogWriter logw = new LogWriter(TAG); 77313fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn PrintWriter pw = new PrintWriter(logw); 774d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy if (mHost != null) { 775ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn try { 7768491eb62f621cd5de4b4caed839be09c77011f53Todd Kennedy mHost.onDump(" ", null, pw, new String[] { }); 777ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn } catch (Exception e) { 778ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn Log.e(TAG, "Failed dumping state", e); 779ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn } 780ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn } else { 781ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn try { 78213fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn dump(" ", null, pw, new String[] { }); 783ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn } catch (Exception e) { 78413fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn Log.e(TAG, "Failed dumping state", e); 785ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn } 786ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn } 78713fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn throw ex; 788ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn } 789ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn 790cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 791cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public FragmentTransaction beginTransaction() { 792cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return new BackStackRecord(this); 793cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 794cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 795cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 796cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean executePendingTransactions() { 797990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean updates = execPendingActions(); 798990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount forcePostponedTransactions(); 799990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return updates; 800cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 801cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 802cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 803cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void popBackStack() { 804990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount enqueueAction(new PopBackStackState(null, -1, 0), false); 805cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 806cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 807cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 808cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean popBackStackImmediate() { 809cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn checkStateLoss(); 810990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return popBackStackImmediate(null, -1, 0); 811cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 812cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 813cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 814cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void popBackStack(final String name, final int flags) { 815990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount enqueueAction(new PopBackStackState(name, -1, flags), false); 816cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 817cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 818cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 819cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean popBackStackImmediate(String name, int flags) { 820cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn checkStateLoss(); 821990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return popBackStackImmediate(name, -1, flags); 822cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 823cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 824cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 825cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void popBackStack(final int id, final int flags) { 826cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (id < 0) { 827cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn throw new IllegalArgumentException("Bad id: " + id); 828cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 829990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount enqueueAction(new PopBackStackState(null, id, flags), false); 830cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 831cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 832cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 833cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean popBackStackImmediate(int id, int flags) { 834cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn checkStateLoss(); 835990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount execPendingActions(); 836cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (id < 0) { 837cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn throw new IllegalArgumentException("Bad id: " + id); 838cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 839990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return popBackStackImmediate(null, id, flags); 840990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 841990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 842990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 843990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Used by all public popBackStackImmediate methods, this executes pending transactions and 844990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * returns true if the pop action did anything, regardless of what other pending 845990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * transactions did. 846990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 847990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @return true if the pop operation did anything or false otherwise. 848990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 849990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private boolean popBackStackImmediate(String name, int id, int flags) { 850990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount execPendingActions(); 851990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ensureExecReady(true); 852990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 853418738949305a8a0e30eba92c125c650048f9c50Adam Powell if (mPrimaryNav != null // We have a primary nav fragment 854418738949305a8a0e30eba92c125c650048f9c50Adam Powell && id < 0 // No valid id (since they're local) 855418738949305a8a0e30eba92c125c650048f9c50Adam Powell && name == null) { // no name to pop to (since they're local) 856418738949305a8a0e30eba92c125c650048f9c50Adam Powell final FragmentManager childManager = mPrimaryNav.peekChildFragmentManager(); 857418738949305a8a0e30eba92c125c650048f9c50Adam Powell if (childManager != null && childManager.popBackStackImmediate()) { 858418738949305a8a0e30eba92c125c650048f9c50Adam Powell // We did something, just not to this specific FragmentManager. Return true. 859418738949305a8a0e30eba92c125c650048f9c50Adam Powell return true; 860418738949305a8a0e30eba92c125c650048f9c50Adam Powell } 861418738949305a8a0e30eba92c125c650048f9c50Adam Powell } 862418738949305a8a0e30eba92c125c650048f9c50Adam Powell 863990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean executePop = popBackStackState(mTmpRecords, mTmpIsPop, name, id, flags); 864990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (executePop) { 865990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mExecutingActions = true; 866990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount try { 867990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount optimizeAndExecuteOps(mTmpRecords, mTmpIsPop); 868990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } finally { 869990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount cleanupExec(); 870990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 871990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 872990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 873990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount doPendingDeferredStart(); 87490b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount burpActive(); 875990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return executePop; 876cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 877cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 878cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 879cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public int getBackStackEntryCount() { 880cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return mBackStack != null ? mBackStack.size() : 0; 881cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 882cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 883cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 884cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public BackStackEntry getBackStackEntryAt(int index) { 885cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return mBackStack.get(index); 886cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 887cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 888cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 889cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void addOnBackStackChangedListener(OnBackStackChangedListener listener) { 890cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStackChangeListeners == null) { 891cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackChangeListeners = new ArrayList<OnBackStackChangedListener>(); 892cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 893cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackChangeListeners.add(listener); 894cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 895cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 896cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 897cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void removeOnBackStackChangedListener(OnBackStackChangedListener listener) { 898cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStackChangeListeners != null) { 899cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackChangeListeners.remove(listener); 900cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 901cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 902cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 903cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 904cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void putFragment(Bundle bundle, String key, Fragment fragment) { 905cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (fragment.mIndex < 0) { 90613fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn throwException(new IllegalStateException("Fragment " + fragment 90713fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn + " is not currently in the FragmentManager")); 908cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 909cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn bundle.putInt(key, fragment.mIndex); 910cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 911cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 912cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 913cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public Fragment getFragment(Bundle bundle, String key) { 914cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int index = bundle.getInt(key, -1); 915cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (index == -1) { 916cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 917cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 918cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mActive.get(index); 919cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f == null) { 9202b336307cf98ca5142db6736812178293d47c500Cyril Mottier throwException(new IllegalStateException("Fragment no longer exists for key " 92113fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn + key + ": index " + index)); 922cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 923cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return f; 924cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 925cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 926cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 92743db3168ca4a4d309f059363054ba60bc22a9ef3George Mount public Collection<Fragment> getFragments() { 92896221034e4a23a2abb83f772a0281bb197ac5ac0George Mount if (mAdded == null) { 92996221034e4a23a2abb83f772a0281bb197ac5ac0George Mount return Collections.EMPTY_LIST; 93096221034e4a23a2abb83f772a0281bb197ac5ac0George Mount } 93196221034e4a23a2abb83f772a0281bb197ac5ac0George Mount synchronized (mAdded) { 93243db3168ca4a4d309f059363054ba60bc22a9ef3George Mount return (Collection<Fragment>) mAdded.clone(); 933418738949305a8a0e30eba92c125c650048f9c50Adam Powell } 9343a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown } 9353a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown 93690b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount /** 93790b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount * This is used by FragmentController to get the Active fragments. 93890b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount * 93990b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount * @return A list of active fragments in the fragment manager, including those that are in the 94090b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount * back stack. 94190b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount */ 94290b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount List<Fragment> getActiveFragments() { 94390b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount if (mActive == null) { 94490b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount return null; 94590b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount } 94690b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount final int count = mActive.size(); 94790b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount ArrayList<Fragment> fragments = new ArrayList<>(count); 94890b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount for (int i = 0; i < count; i++) { 94990b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount fragments.add(mActive.valueAt(i)); 95090b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount } 95190b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount return fragments; 95290b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount } 95390b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount 95490b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount /** 95590b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount * Used by FragmentController to get the number of Active Fragments. 95690b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount * 95790b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount * @return The number of active fragments. 95890b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount */ 95990b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount int getActiveFragmentCount() { 96090b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount if (mActive == null) { 96190b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount return 0; 96290b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount } 96390b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount return mActive.size(); 96490b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount } 96590b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount 9663a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown @Override 9675c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn public Fragment.SavedState saveFragmentInstanceState(Fragment fragment) { 9685c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn if (fragment.mIndex < 0) { 96913fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn throwException( new IllegalStateException("Fragment " + fragment 97013fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn + " is not currently in the FragmentManager")); 9715c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 9725c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn if (fragment.mState > Fragment.INITIALIZING) { 9735c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn Bundle result = saveFragmentBasicState(fragment); 9745c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn return result != null ? new Fragment.SavedState(result) : null; 9755c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 9765c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn return null; 9775c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 9785c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn 9795c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn @Override 98001df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler public boolean isDestroyed() { 98101df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler return mDestroyed; 98201df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler } 98301df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler 98401df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler @Override 985cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public String toString() { 986cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn StringBuilder sb = new StringBuilder(128); 987cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn sb.append("FragmentManager{"); 988cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn sb.append(Integer.toHexString(System.identityHashCode(this))); 989cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn sb.append(" in "); 9900adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (mParent != null) { 9910adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn DebugUtils.buildShortClassTag(mParent, sb); 9920adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn } else { 993d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy DebugUtils.buildShortClassTag(mHost, sb); 9940adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn } 995cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn sb.append("}}"); 996cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return sb.toString(); 997cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 998cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 999cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 1000cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { 1001cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn String innerPrefix = prefix + " "; 1002cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1003cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int N; 1004cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mActive != null) { 1005cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn N = mActive.size(); 1006cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (N > 0) { 1007cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print("Active Fragments in "); 1008cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(Integer.toHexString(System.identityHashCode(this))); 1009cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.println(":"); 1010cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<N; i++) { 101190b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount Fragment f = mActive.valueAt(i); 1012cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" #"); writer.print(i); 1013cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(": "); writer.println(f); 1014cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f != null) { 1015cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.dump(innerPrefix, fd, writer, args); 1016cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1017cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1018cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1019cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1020cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1021cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mAdded != null) { 1022cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn N = mAdded.size(); 1023cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (N > 0) { 1024cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.println("Added Fragments:"); 1025cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<N; i++) { 1026cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mAdded.get(i); 1027cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" #"); writer.print(i); 1028cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(": "); writer.println(f.toString()); 1029cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1030cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1031cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1032cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1033cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mCreatedMenus != null) { 1034cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn N = mCreatedMenus.size(); 1035cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (N > 0) { 1036cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.println("Fragments Created Menus:"); 1037cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<N; i++) { 1038cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mCreatedMenus.get(i); 1039cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" #"); writer.print(i); 1040cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(": "); writer.println(f.toString()); 1041cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1042cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1043cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1044cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1045cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStack != null) { 1046cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn N = mBackStack.size(); 1047cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (N > 0) { 1048cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.println("Back Stack:"); 1049cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<N; i++) { 1050cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn BackStackRecord bs = mBackStack.get(i); 1051cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" #"); writer.print(i); 1052cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(": "); writer.println(bs.toString()); 1053cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn bs.dump(innerPrefix, fd, writer, args); 1054cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1055cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1056cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1057cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1058cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn synchronized (this) { 1059cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStackIndices != null) { 1060cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn N = mBackStackIndices.size(); 1061cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (N > 0) { 1062cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.println("Back Stack Indices:"); 1063cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<N; i++) { 1064cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn BackStackRecord bs = mBackStackIndices.get(i); 1065cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" #"); writer.print(i); 1066cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(": "); writer.println(bs); 1067cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1068cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1069cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1070cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1071cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mAvailBackStackIndices != null && mAvailBackStackIndices.size() > 0) { 1072cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print("mAvailBackStackIndices: "); 1073cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.println(Arrays.toString(mAvailBackStackIndices.toArray())); 1074cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1075cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1076cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1077cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mPendingActions != null) { 1078cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn N = mPendingActions.size(); 1079cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (N > 0) { 1080cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.println("Pending Actions:"); 1081cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<N; i++) { 1082990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount OpGenerator r = mPendingActions.get(i); 1083cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" #"); writer.print(i); 1084cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(": "); writer.println(r); 1085cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1086cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1087cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1088cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1089cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.println("FragmentManager misc state:"); 1090d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy writer.print(prefix); writer.print(" mHost="); writer.println(mHost); 10910adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn writer.print(prefix); writer.print(" mContainer="); writer.println(mContainer); 10920adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (mParent != null) { 10930adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn writer.print(prefix); writer.print(" mParent="); writer.println(mParent); 10940adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn } 1095cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" mCurState="); writer.print(mCurState); 1096cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(" mStateSaved="); writer.print(mStateSaved); 1097cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(" mDestroyed="); writer.println(mDestroyed); 1098cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mNeedMenuInvalidate) { 1099cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" mNeedMenuInvalidate="); 1100cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.println(mNeedMenuInvalidate); 1101cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1102cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mNoTransactionsBecause != null) { 1103cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" mNoTransactionsBecause="); 1104cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.println(mNoTransactionsBecause); 1105cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1106cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1107cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 11089277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn static final Interpolator DECELERATE_QUINT = new DecelerateInterpolator(2.5f); 11099277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn static final Interpolator DECELERATE_CUBIC = new DecelerateInterpolator(1.5f); 11109277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn static final Interpolator ACCELERATE_QUINT = new AccelerateInterpolator(2.5f); 11119277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn static final Interpolator ACCELERATE_CUBIC = new AccelerateInterpolator(1.5f); 1112dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 11139277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn static final int ANIM_DUR = 220; 1114dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 11159277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn static Animation makeOpenCloseAnimation(Context context, float startScale, 11169277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn float endScale, float startAlpha, float endAlpha) { 11179277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn AnimationSet set = new AnimationSet(false); 11189277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn ScaleAnimation scale = new ScaleAnimation(startScale, endScale, startScale, endScale, 11199277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn Animation.RELATIVE_TO_SELF, .5f, Animation.RELATIVE_TO_SELF, .5f); 11209277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn scale.setInterpolator(DECELERATE_QUINT); 11219277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn scale.setDuration(ANIM_DUR); 11229277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn set.addAnimation(scale); 11239277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn AlphaAnimation alpha = new AlphaAnimation(startAlpha, endAlpha); 11249277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn alpha.setInterpolator(DECELERATE_CUBIC); 11259277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn alpha.setDuration(ANIM_DUR); 11269277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn set.addAnimation(alpha); 11279277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn return set; 11289277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn } 1129dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 11309277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn static Animation makeFadeAnimation(Context context, float start, float end) { 11319277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn AlphaAnimation anim = new AlphaAnimation(start, end); 11329277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn anim.setInterpolator(DECELERATE_CUBIC); 11339277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn anim.setDuration(ANIM_DUR); 11349277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn return anim; 11359277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn } 113603526560f132021f8fd7290259762ab362d4d567Doris Liu 11379277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn Animation loadAnimation(Fragment fragment, int transit, boolean enter, 1138cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int transitionStyle) { 1139990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Animation animObj = fragment.onCreateAnimation(transit, enter, fragment.getNextAnim()); 1140cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (animObj != null) { 1141cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return animObj; 1142cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1143dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1144990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (fragment.getNextAnim() != 0) { 1145990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Animation anim = AnimationUtils.loadAnimation(mHost.getContext(), 1146990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.getNextAnim()); 1147cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (anim != null) { 1148cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return anim; 1149cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1150cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1151dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1152cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (transit == 0) { 1153cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 1154cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1155dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1156cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int styleIndex = transitToStyleIndex(transit, enter); 1157cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (styleIndex < 0) { 1158cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 1159cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 116003526560f132021f8fd7290259762ab362d4d567Doris Liu 11619277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn switch (styleIndex) { 11629277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn case ANIM_STYLE_OPEN_ENTER: 1163d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy return makeOpenCloseAnimation(mHost.getContext(), 1.125f, 1.0f, 0, 1); 11649277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn case ANIM_STYLE_OPEN_EXIT: 1165d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy return makeOpenCloseAnimation(mHost.getContext(), 1.0f, .975f, 1, 0); 11669277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn case ANIM_STYLE_CLOSE_ENTER: 1167d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy return makeOpenCloseAnimation(mHost.getContext(), .975f, 1.0f, 0, 1); 11689277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn case ANIM_STYLE_CLOSE_EXIT: 1169d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy return makeOpenCloseAnimation(mHost.getContext(), 1.0f, 1.075f, 1, 0); 11709277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn case ANIM_STYLE_FADE_ENTER: 1171d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy return makeFadeAnimation(mHost.getContext(), 0, 1); 11729277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn case ANIM_STYLE_FADE_EXIT: 1173d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy return makeFadeAnimation(mHost.getContext(), 1, 0); 11749277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn } 1175dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 11768491eb62f621cd5de4b4caed839be09c77011f53Todd Kennedy if (transitionStyle == 0 && mHost.onHasWindowAnimations()) { 11778491eb62f621cd5de4b4caed839be09c77011f53Todd Kennedy transitionStyle = mHost.onGetWindowAnimations(); 1178cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1179cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (transitionStyle == 0) { 1180cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 1181cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1182dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1183cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn //TypedArray attrs = mActivity.obtainStyledAttributes(transitionStyle, 1184cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // com.android.internal.R.styleable.FragmentAnimation); 1185cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn //int anim = attrs.getResourceId(styleIndex, 0); 1186cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn //attrs.recycle(); 1187dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1188cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn //if (anim == 0) { 1189cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // return null; 1190cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn //} 1191dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1192cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn //return AnimatorInflater.loadAnimator(mActivity, anim); 1193cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 1194cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1195dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1196abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell public void performPendingDeferredStart(Fragment f) { 1197abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell if (f.mDeferStart) { 119879398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell if (mExecutingActions) { 119979398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell // Wait until we're done executing our pending transactions 120079398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell mHavePendingDeferredStart = true; 120179398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell return; 120279398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell } 1203abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell f.mDeferStart = false; 12045506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn moveToState(f, mCurState, 0, 0, false); 1205abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell } 1206abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell } 1207abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell 120803526560f132021f8fd7290259762ab362d4d567Doris Liu /** 120903526560f132021f8fd7290259762ab362d4d567Doris Liu * Sets the to be animated view on hardware layer during the animation. Note 121003526560f132021f8fd7290259762ab362d4d567Doris Liu * that calling this will replace any existing animation listener on the animation 121103526560f132021f8fd7290259762ab362d4d567Doris Liu * with a new one, as animations do not support more than one listeners. Therefore, 121203526560f132021f8fd7290259762ab362d4d567Doris Liu * animations that already have listeners should do the layer change operations 121303526560f132021f8fd7290259762ab362d4d567Doris Liu * in their existing listeners, rather than calling this function. 121403526560f132021f8fd7290259762ab362d4d567Doris Liu */ 121503526560f132021f8fd7290259762ab362d4d567Doris Liu private void setHWLayerAnimListenerIfAlpha(final View v, Animation anim) { 121603526560f132021f8fd7290259762ab362d4d567Doris Liu if (v == null || anim == null) { 121703526560f132021f8fd7290259762ab362d4d567Doris Liu return; 121803526560f132021f8fd7290259762ab362d4d567Doris Liu } 121903526560f132021f8fd7290259762ab362d4d567Doris Liu if (shouldRunOnHWLayer(v, anim)) { 1220d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu AnimationListener originalListener = null; 1221d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu try { 1222d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu if (sAnimationListenerField == null) { 1223d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu sAnimationListenerField = Animation.class.getDeclaredField("mListener"); 1224d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu sAnimationListenerField.setAccessible(true); 1225d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu } 1226d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu originalListener = (AnimationListener) sAnimationListenerField.get(anim); 1227d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu } catch (NoSuchFieldException e) { 1228d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu Log.e(TAG, "No field with the name mListener is found in Animation class", e); 1229d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu } catch (IllegalAccessException e) { 1230d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu Log.e(TAG, "Cannot access Animation's mListener field", e); 1231d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu } 1232d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu // If there's already a listener set on the animation, we need wrap the new listener 1233d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu // around the existing listener, so that they will both get animation listener 1234d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu // callbacks. 1235fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 1236d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu anim.setAnimationListener(new AnimateOnHWLayerIfNeededListener(v, anim, 1237d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu originalListener)); 123803526560f132021f8fd7290259762ab362d4d567Doris Liu } 123903526560f132021f8fd7290259762ab362d4d567Doris Liu } 124003526560f132021f8fd7290259762ab362d4d567Doris Liu 1241fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell boolean isStateAtLeast(int state) { 1242fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell return mCurState >= state; 1243fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell } 1244fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell 12455506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn void moveToState(Fragment f, int newState, int transit, int transitionStyle, 12465506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn boolean keepActive) { 1247cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Fragments that are not currently added will sit in the onCreate() state. 124874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn if ((!f.mAdded || f.mDetached) && newState > Fragment.CREATED) { 1249cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn newState = Fragment.CREATED; 1250cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 12512c4b5dbfee5232bcbbcb74b84ce9147b62a9d789Dianne Hackborn if (f.mRemoving && newState > f.mState) { 12525a97188ba9e2fe80ef31c1bd269f3963c394c1b4George Mount if (f.mState == Fragment.INITIALIZING && f.isInBackStack()) { 12535a97188ba9e2fe80ef31c1bd269f3963c394c1b4George Mount // Allow the fragment to be created so that it can be saved later. 12545a97188ba9e2fe80ef31c1bd269f3963c394c1b4George Mount newState = Fragment.CREATED; 12555a97188ba9e2fe80ef31c1bd269f3963c394c1b4George Mount } else { 12565a97188ba9e2fe80ef31c1bd269f3963c394c1b4George Mount // While removing a fragment, we can't change it to a higher state. 12575a97188ba9e2fe80ef31c1bd269f3963c394c1b4George Mount newState = f.mState; 12585a97188ba9e2fe80ef31c1bd269f3963c394c1b4George Mount } 12592c4b5dbfee5232bcbbcb74b84ce9147b62a9d789Dianne Hackborn } 12606cafd27a3c89dfed10d7e226dc6168307513d4a6Adam Powell // Defer start if requested; don't allow it to move to STARTED or higher 12616cafd27a3c89dfed10d7e226dc6168307513d4a6Adam Powell // if it's not already started. 12626cafd27a3c89dfed10d7e226dc6168307513d4a6Adam Powell if (f.mDeferStart && f.mState < Fragment.STARTED && newState > Fragment.STOPPED) { 1263abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell newState = Fragment.STOPPED; 1264abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell } 126537149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell if (f.mState <= newState) { 12669277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn // For fragments that are created from a layout, when restoring from 12679277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn // state we don't want to allow them to be created until they are 12689277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn // being reloaded from the layout. 12699277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn if (f.mFromLayout && !f.mInLayout) { 12709277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn return; 1271dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas } 1272990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.getAnimatingAway() != null) { 1273cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // The fragment is currently being animated... but! Now we 1274cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // want to move our state back up. Give up on waiting for the 1275cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // animation, move to whatever the final state should be once 1276cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // the animation is done, and then we can proceed from there. 1277990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.setAnimatingAway(null); 1278990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveToState(f, f.getStateAfterAnimating(), 0, 0, true); 1279cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1280cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn switch (f.mState) { 1281cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case Fragment.INITIALIZING: 128237149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell if (newState > Fragment.INITIALIZING) { 128337149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell if (DEBUG) Log.v(TAG, "moveto CREATED: " + f); 128437149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell if (f.mSavedFragmentState != null) { 128537149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mSavedFragmentState.setClassLoader(mHost.getContext() 128637149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell .getClassLoader()); 128737149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray( 128837149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell FragmentManagerImpl.VIEW_STATE_TAG); 128937149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mTarget = getFragment(f.mSavedFragmentState, 129037149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell FragmentManagerImpl.TARGET_STATE_TAG); 129137149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell if (f.mTarget != null) { 129237149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mTargetRequestCode = f.mSavedFragmentState.getInt( 129337149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0); 129437149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell } 129537149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mUserVisibleHint = f.mSavedFragmentState.getBoolean( 129637149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true); 129737149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell if (!f.mUserVisibleHint) { 129837149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mDeferStart = true; 129937149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell if (newState > Fragment.STOPPED) { 130037149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell newState = Fragment.STOPPED; 130137149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell } 130279398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell } 130379398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell } 1304a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell 130537149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mHost = mHost; 130637149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mParentFragment = mParent; 130737149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mFragmentManager = mParent != null 130837149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell ? mParent.mChildFragmentManager : mHost.getFragmentManagerImpl(); 1309a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell 1310a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell // If we have a target fragment, push it along to at least CREATED 1311a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell // so that this one can rely on it as an initialized dependency. 1312a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell if (f.mTarget != null) { 131396767975440de77e44a231e6ef66b374b1403bd0George Mount if (mActive.get(f.mTarget.mIndex) != f.mTarget) { 1314a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell throw new IllegalStateException("Fragment " + f 1315a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell + " declared target fragment " + f.mTarget 1316a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell + " that does not belong to this FragmentManager!"); 1317a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell } 1318a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell if (f.mTarget.mState < Fragment.CREATED) { 1319a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell moveToState(f.mTarget, Fragment.CREATED, 0, 0, true); 1320a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell } 1321a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell } 1322a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell 132337149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell dispatchOnFragmentPreAttached(f, mHost.getContext(), false); 132437149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mCalled = false; 132537149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.onAttach(mHost.getContext()); 132637149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell if (!f.mCalled) { 132737149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell throw new SuperNotCalledException("Fragment " + f 132837149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell + " did not call through to super.onAttach()"); 132937149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell } 133037149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell if (f.mParentFragment == null) { 133137149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell mHost.onAttachFragment(f); 133237149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell } else { 133337149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mParentFragment.onAttachFragment(f); 133437149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell } 133537149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell dispatchOnFragmentAttached(f, mHost.getContext(), false); 13360adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn 133737149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell if (!f.mRetaining) { 133837149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.performCreate(f.mSavedFragmentState); 133937149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell dispatchOnFragmentCreated(f, f.mSavedFragmentState, false); 1340cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 134137149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.restoreChildFragmentState(f.mSavedFragmentState); 134237149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mState = Fragment.CREATED; 1343cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 134437149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mRetaining = false; 1345cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 134637149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell 1347cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case Fragment.CREATED: 134837149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell // This is outside the if statement below on purpose; we want this to run 134937149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell // even if we do a moveToState from CREATED => *, CREATED => CREATED, and 135037149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell // * => CREATED as part of the case fallthrough above. 135137149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell ensureInflatedFragmentView(f); 135237149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell 1353cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (newState > Fragment.CREATED) { 1354e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f); 1355cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (!f.mFromLayout) { 1356cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ViewGroup container = null; 1357cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mContainerId != 0) { 135836bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell if (f.mContainerId == View.NO_ID) { 135936bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell throwException(new IllegalArgumentException( 136036bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell "Cannot create fragment " 136136bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell + f 136236bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell + " for a container view with no id")); 136336bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell } 136436bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell container = (ViewGroup) mContainer.onFindViewById(f.mContainerId); 1365cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (container == null && !f.mRestored) { 136636bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell String resName; 136736bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell try { 136836bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell resName = f.getResources().getResourceName(f.mContainerId); 136936bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell } catch (NotFoundException e) { 137036bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell resName = "unknown"; 137136bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell } 137213fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn throwException(new IllegalArgumentException( 137313fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn "No view found for id 0x" 137413fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn + Integer.toHexString(f.mContainerId) + " (" 137536bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell + resName 137613fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn + ") for fragment " + f)); 1377cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1378cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1379cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mContainer = container; 13800abeed582ee0a105edb41181d76e8ee034750f22George Mount f.mView = f.performCreateView(f.onGetLayoutInflater( 13810adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.mSavedFragmentState), container, f.mSavedFragmentState); 1382cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mView != null) { 1383cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mInnerView = f.mView; 1384fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas f.mView.setSaveFromParentEnabled(false); 1385cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (container != null) { 1386cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn container.addView(f.mView); 1387990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1388990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.mHidden) { 1389990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.mView.setVisibility(View.GONE); 1390cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1391e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn f.onViewCreated(f.mView, f.mSavedFragmentState); 1392267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState, 1393267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell false); 1394d88ddfd4577e46829bf87124ad335d3cb82c3895George Mount // Only animate the view if it is visible. This is done after 1395d88ddfd4577e46829bf87124ad335d3cb82c3895George Mount // dispatchOnFragmentViewCreated in case visibility is changed 1396d88ddfd4577e46829bf87124ad335d3cb82c3895George Mount f.mIsNewlyAdded = (f.mView.getVisibility() == View.VISIBLE) 1397d88ddfd4577e46829bf87124ad335d3cb82c3895George Mount && f.mContainer != null; 1398cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 1399cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mInnerView = null; 1400cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1401cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 14020adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn 14030adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.performActivityCreated(f.mSavedFragmentState); 1404267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell dispatchOnFragmentActivityCreated(f, f.mSavedFragmentState, false); 1405e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (f.mView != null) { 14060adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.restoreViewState(f.mSavedFragmentState); 1407e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1408cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mSavedFragmentState = null; 1409cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1410cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case Fragment.ACTIVITY_CREATED: 14119375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell if (newState > Fragment.ACTIVITY_CREATED) { 14129375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell f.mState = Fragment.STOPPED; 14139375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell } 1414e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn case Fragment.STOPPED: 1415e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (newState > Fragment.STOPPED) { 1416cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "moveto STARTED: " + f); 14179c53b844bd525e6a04e17291efc38713893074cdDianne Hackborn f.performStart(); 1418267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell dispatchOnFragmentStarted(f, false); 1419cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1420cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case Fragment.STARTED: 1421cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (newState > Fragment.STARTED) { 1422cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f); 14230adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.performResume(); 1424267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell dispatchOnFragmentResumed(f, false); 14254e6647fe2551985f33407acd712a4942b090207aDianne Hackborn f.mSavedFragmentState = null; 14264e6647fe2551985f33407acd712a4942b090207aDianne Hackborn f.mSavedViewState = null; 1427cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1428cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1429cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else if (f.mState > newState) { 1430cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn switch (f.mState) { 1431cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case Fragment.RESUMED: 1432cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (newState < Fragment.RESUMED) { 1433cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "movefrom RESUMED: " + f); 14340adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.performPause(); 1435267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell dispatchOnFragmentPaused(f, false); 1436cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1437cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case Fragment.STARTED: 1438cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (newState < Fragment.STARTED) { 1439cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "movefrom STARTED: " + f); 1440cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.performStop(); 1441267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell dispatchOnFragmentStopped(f, false); 1442cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1443e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn case Fragment.STOPPED: 1444218c1e661578e2a17928f7dbb590b43d1c79aeb7Dianne Hackborn if (newState < Fragment.STOPPED) { 1445218c1e661578e2a17928f7dbb590b43d1c79aeb7Dianne Hackborn if (DEBUG) Log.v(TAG, "movefrom STOPPED: " + f); 1446218c1e661578e2a17928f7dbb590b43d1c79aeb7Dianne Hackborn f.performReallyStop(); 1447218c1e661578e2a17928f7dbb590b43d1c79aeb7Dianne Hackborn } 1448cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case Fragment.ACTIVITY_CREATED: 1449cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (newState < Fragment.ACTIVITY_CREATED) { 1450e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (DEBUG) Log.v(TAG, "movefrom ACTIVITY_CREATED: " + f); 1451cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mView != null) { 1452cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Need to save the current view state if not 1453cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // done already. 14548491eb62f621cd5de4b4caed839be09c77011f53Todd Kennedy if (mHost.onShouldSaveFragmentState(f) && f.mSavedViewState == null) { 1455cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn saveFragmentViewState(f); 1456cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1457cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 14589c53b844bd525e6a04e17291efc38713893074cdDianne Hackborn f.performDestroyView(); 1459267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell dispatchOnFragmentViewDestroyed(f, false); 1460cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mView != null && f.mContainer != null) { 1461cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Animation anim = null; 1462990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mCurState > Fragment.INITIALIZING && !mDestroyed 14630bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount && f.mView.getVisibility() == View.VISIBLE 14640bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount && f.mPostponedAlpha >= 0) { 14659277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn anim = loadAnimation(f, transit, false, 1466cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn transitionStyle); 1467cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 14680bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount f.mPostponedAlpha = 0; 1469cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (anim != null) { 1470cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn final Fragment fragment = f; 1471990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.setAnimatingAway(f.mView); 1472990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.setStateAfterAnimating(newState); 147303526560f132021f8fd7290259762ab362d4d567Doris Liu final View viewToAnimate = f.mView; 147403526560f132021f8fd7290259762ab362d4d567Doris Liu anim.setAnimationListener(new AnimateOnHWLayerIfNeededListener( 147503526560f132021f8fd7290259762ab362d4d567Doris Liu viewToAnimate, anim) { 1476cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 1477cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void onAnimationEnd(Animation animation) { 147803526560f132021f8fd7290259762ab362d4d567Doris Liu super.onAnimationEnd(animation); 1479990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (fragment.getAnimatingAway() != null) { 1480990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.setAnimatingAway(null); 1481990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveToState(fragment, fragment.getStateAfterAnimating(), 14825506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn 0, 0, false); 1483cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1484cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1485cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn }); 14869277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn f.mView.startAnimation(anim); 1487cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 14888aa950177d9290b005f0817485f241ddc41c8026George Mount f.mContainer.removeView(f.mView); 1489cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1490cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mContainer = null; 1491cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mView = null; 1492cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mInnerView = null; 149337149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mInLayout = false; 1494cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1495cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case Fragment.CREATED: 1496cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (newState < Fragment.CREATED) { 1497cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mDestroyed) { 1498990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.getAnimatingAway() != null) { 1499cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // The fragment's containing activity is 1500cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // being destroyed, but this fragment is 1501cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // currently animating away. Stop the 1502cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // animation right now -- it is not needed, 1503cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // and we can't wait any more on destroying 1504cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // the fragment. 1505990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount View v = f.getAnimatingAway(); 1506990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.setAnimatingAway(null); 1507cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn v.clearAnimation(); 1508cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1509cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1510990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.getAnimatingAway() != null) { 1511cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // We are waiting for the fragment's view to finish 1512cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // animating away. Just make a note of the state 1513cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // the fragment now should move to once the animation 1514cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // is done. 1515990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.setStateAfterAnimating(newState); 15162c4b5dbfee5232bcbbcb74b84ce9147b62a9d789Dianne Hackborn newState = Fragment.CREATED; 1517cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 1518cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "movefrom CREATED: " + f); 1519cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (!f.mRetaining) { 15200adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.performDestroy(); 1521267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell dispatchOnFragmentDestroyed(f, false); 152220735a45289fdad3d5d31228992e0dccd3d5dd4fAdam Powell } else { 1523b054427688e7cf0475bec09da9a3fb7688881459Adam Powell f.mState = Fragment.INITIALIZING; 1524cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1525cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1526916455675ddb34d0eb848b2355550268d82c3ce7Adam Powell f.performDetach(); 1527267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell dispatchOnFragmentDetached(f, false); 15285506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn if (!keepActive) { 15295506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn if (!f.mRetaining) { 15305506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn makeInactive(f); 15315506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn } else { 1532d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy f.mHost = null; 15336252d78085a07c9d6bb4645a4e8086bf23b0a49aTim Kilbourn f.mParentFragment = null; 15345506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn f.mFragmentManager = null; 15355506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn } 15362c4b5dbfee5232bcbbcb74b84ce9147b62a9d789Dianne Hackborn } 1537cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1538cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1539cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1540cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 154120735a45289fdad3d5d31228992e0dccd3d5dd4fAdam Powell 154220735a45289fdad3d5d31228992e0dccd3d5dd4fAdam Powell if (f.mState != newState) { 154320735a45289fdad3d5d31228992e0dccd3d5dd4fAdam Powell Log.w(TAG, "moveToState: Fragment state for " + f + " not updated inline; " 154420735a45289fdad3d5d31228992e0dccd3d5dd4fAdam Powell + "expected state " + newState + " found " + f.mState); 154520735a45289fdad3d5d31228992e0dccd3d5dd4fAdam Powell f.mState = newState; 154620735a45289fdad3d5d31228992e0dccd3d5dd4fAdam Powell } 1547cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1548dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1549cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn void moveToState(Fragment f) { 15505506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn moveToState(f, mCurState, 0, 0, false); 1551cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1552cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 155337149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell void ensureInflatedFragmentView(Fragment f) { 155437149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell if (f.mFromLayout && !f.mPerformedCreateView) { 15550abeed582ee0a105edb41181d76e8ee034750f22George Mount f.mView = f.performCreateView(f.onGetLayoutInflater( 155637149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mSavedFragmentState), null, f.mSavedFragmentState); 155737149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell if (f.mView != null) { 155837149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mInnerView = f.mView; 1559fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas f.mView.setSaveFromParentEnabled(false); 156037149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell if (f.mHidden) f.mView.setVisibility(View.GONE); 156137149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.onViewCreated(f.mView, f.mSavedFragmentState); 156237149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState, false); 156337149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell } else { 156437149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mInnerView = null; 156537149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell } 156637149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell } 156737149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell } 156837149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell 1569990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 1570990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Fragments that have been shown or hidden don't have their visibility changed or 1571990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * animations run during the {@link #showFragment(Fragment)} or {@link #hideFragment(Fragment)} 1572990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * calls. After fragments are brought to their final state in 1573990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@link #moveFragmentToExpectedState(Fragment)} the fragments that have been shown or 1574990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * hidden must have their visibility changed and their animations started here. 1575990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 1576990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param fragment The fragment with mHiddenChanged = true that should change its View's 1577990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * visibility and start the show or hide animation. 1578990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 1579990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount void completeShowHideFragment(final Fragment fragment) { 1580990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (fragment.mView != null) { 1581990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Animation anim = loadAnimation(fragment, fragment.getNextTransition(), 1582990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount !fragment.mHidden, fragment.getNextTransitionStyle()); 1583990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (anim != null) { 1584990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount setHWLayerAnimListenerIfAlpha(fragment.mView, anim); 1585990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.mView.startAnimation(anim); 1586990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount setHWLayerAnimListenerIfAlpha(fragment.mView, anim); 1587990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount anim.start(); 1588990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1589667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount final int visibility = fragment.mHidden && !fragment.isHideReplaced() 1590667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount ? View.GONE 1591667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount : View.VISIBLE; 1592990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.mView.setVisibility(visibility); 1593667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount if (fragment.isHideReplaced()) { 1594667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount fragment.setHideReplaced(false); 1595667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount } 1596990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1597990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (fragment.mAdded && fragment.mHasMenu && fragment.mMenuVisible) { 1598990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mNeedMenuInvalidate = true; 1599990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1600990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.mHiddenChanged = false; 1601990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.onHiddenChanged(fragment.mHidden); 1602cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1603dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1604990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 1605990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Moves a fragment to its expected final state or the fragment manager's state, depending 1606990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * on whether the fragment manager's state is raised properly. 1607990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 1608990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param f The fragment to change. 1609990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 1610990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount void moveFragmentToExpectedState(Fragment f) { 1611990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f == null) { 1612990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return; 1613990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1614990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int nextState = mCurState; 1615990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.mRemoving) { 1616990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.isInBackStack()) { 161740e1750a5ed6cca1efb47e10af4db19abecd9fd5George Mount nextState = Math.min(nextState, Fragment.CREATED); 1618990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } else { 161940e1750a5ed6cca1efb47e10af4db19abecd9fd5George Mount nextState = Math.min(nextState, Fragment.INITIALIZING); 1620990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1621cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1622990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveToState(f, nextState, f.getNextTransition(), f.getNextTransitionStyle(), false); 16230adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn 1624990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.mView != null) { 1625990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Move the view if it is out of order 1626990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Fragment underFragment = findFragmentUnder(f); 1627990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (underFragment != null) { 1628990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final View underView = underFragment.mView; 1629990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // make sure this fragment is in the right order. 1630990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final ViewGroup container = f.mContainer; 1631990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int underIndex = container.indexOfChild(underView); 1632990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int viewIndex = container.indexOfChild(f.mView); 1633990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (viewIndex < underIndex) { 1634990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount container.removeViewAt(viewIndex); 1635990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount container.addView(f.mView, underIndex); 1636990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1637990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1638990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.mIsNewlyAdded && f.mContainer != null) { 1639990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Make it visible and run the animations 16409d359be2fec790cf02c3201c89ff37d425d35058Aurimas Liutikas if (f.mPostponedAlpha > 0f) { 16410bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount f.mView.setAlpha(f.mPostponedAlpha); 16420bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount } 16430bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount f.mPostponedAlpha = 0f; 1644990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.mIsNewlyAdded = false; 1645990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // run animations: 1646990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Animation anim = loadAnimation(f, f.getNextTransition(), true, 1647990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.getNextTransitionStyle()); 1648990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (anim != null) { 1649990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount setHWLayerAnimListenerIfAlpha(f.mView, anim); 1650990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.mView.startAnimation(anim); 1651990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1652990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1653990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1654990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.mHiddenChanged) { 1655990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount completeShowHideFragment(f); 1656990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1657990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1658990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 165977f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount /** 166077f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount * Changes the state of the fragment manager to {@code newState}. If the fragment manager 166177f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount * changes state or {@code always} is {@code true}, any fragments within it have their 166277f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount * states updated as well. 166377f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount * 166477f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount * @param newState The new state for the fragment manager 166577f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount * @param always If {@code true}, all fragments update their state, even 166677f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount * if {@code newState} matches the current fragment manager's state. 166777f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount */ 166877f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount void moveToState(int newState, boolean always) { 1669990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mHost == null && newState != Fragment.INITIALIZING) { 1670990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount throw new IllegalStateException("No activity"); 1671cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 16720adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn 167377f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount if (!always && newState == mCurState) { 167477f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount return; 167577f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount } 167677f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount 1677cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mCurState = newState; 1678990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 1679cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mActive != null) { 1680abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell boolean loadersRunning = false; 1681990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 1682990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Must add them in the proper order. mActive fragments may be out of order 1683990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mAdded != null) { 1684990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int numAdded = mAdded.size(); 1685990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numAdded; i++) { 1686990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Fragment f = mAdded.get(i); 1687990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveFragmentToExpectedState(f); 1688990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.mLoaderManager != null) { 1689990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount loadersRunning |= f.mLoaderManager.hasRunningLoaders(); 1690990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1691990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1692990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1693990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 1694990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Now iterate through all active fragments. These will include those that are removed 1695990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // and detached. 1696990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int numActive = mActive.size(); 1697990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numActive; i++) { 169890b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount Fragment f = mActive.valueAt(i); 1699990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f != null && (f.mRemoving || f.mDetached) && !f.mIsNewlyAdded) { 1700990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveFragmentToExpectedState(f); 1701abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell if (f.mLoaderManager != null) { 1702abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell loadersRunning |= f.mLoaderManager.hasRunningLoaders(); 1703abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell } 1704cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1705cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1706cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1707abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell if (!loadersRunning) { 1708abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell startPendingDeferredFragments(); 1709abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell } 1710abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell 1711d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy if (mNeedMenuInvalidate && mHost != null && mCurState == Fragment.RESUMED) { 17128491eb62f621cd5de4b4caed839be09c77011f53Todd Kennedy mHost.onSupportInvalidateOptionsMenu(); 1713cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mNeedMenuInvalidate = false; 1714cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1715cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1716cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1717abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell 1718abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell void startPendingDeferredFragments() { 17191199ae7067cdf8cf3eb30c057a61ae71a0aea1e5Adam Powell if (mActive == null) return; 17201199ae7067cdf8cf3eb30c057a61ae71a0aea1e5Adam Powell 1721abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell for (int i=0; i<mActive.size(); i++) { 172290b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount Fragment f = mActive.valueAt(i); 1723abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell if (f != null) { 1724abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell performPendingDeferredStart(f); 1725abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell } 1726abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell } 1727abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell } 1728dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1729cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn void makeActive(Fragment f) { 1730cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mIndex >= 0) { 1731cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return; 1732cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1733dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 173490b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount f.setIndex(mNextFragmentIndex++, mParent); 173590b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount if (mActive == null) { 173690b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount mActive = new SparseArray<>(); 1737cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 173890b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount mActive.put(f.mIndex, f); 1739be2c79d9a5439922030d2a3846c81c61f0e16912Dianne Hackborn if (DEBUG) Log.v(TAG, "Allocated fragment index " + f); 1740cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1741dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1742cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn void makeInactive(Fragment f) { 1743cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mIndex < 0) { 1744cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return; 1745cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1746dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1747be2c79d9a5439922030d2a3846c81c61f0e16912Dianne Hackborn if (DEBUG) Log.v(TAG, "Freeing fragment index " + f); 174890b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount // Don't remove yet. That happens in burpActive(). This prevents 174990b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount // concurrent modification while iterating over mActive 175090b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount mActive.put(f.mIndex, null); 175190b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount 1752d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy mHost.inactivateFragment(f.mWho); 17539c53b844bd525e6a04e17291efc38713893074cdDianne Hackborn f.initState(); 1754cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1755dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1756cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void addFragment(Fragment fragment, boolean moveToStateNow) { 1757cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mAdded == null) { 1758cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAdded = new ArrayList<Fragment>(); 1759cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1760cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "add: " + fragment); 1761e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn makeActive(fragment); 1762e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (!fragment.mDetached) { 17633a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn if (mAdded.contains(fragment)) { 17643a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn throw new IllegalStateException("Fragment already added: " + fragment); 17653a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn } 176696221034e4a23a2abb83f772a0281bb197ac5ac0George Mount synchronized (mAdded) { 176796221034e4a23a2abb83f772a0281bb197ac5ac0George Mount mAdded.add(fragment); 176896221034e4a23a2abb83f772a0281bb197ac5ac0George Mount } 1769e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn fragment.mAdded = true; 1770e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn fragment.mRemoving = false; 1771990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (fragment.mView == null) { 1772990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.mHiddenChanged = false; 1773990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 17742a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn if (fragment.mHasMenu && fragment.mMenuVisible) { 1775e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn mNeedMenuInvalidate = true; 1776e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1777e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (moveToStateNow) { 1778e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn moveToState(fragment); 1779e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1780cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1781cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1782dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1783990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void removeFragment(Fragment fragment) { 1784cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "remove: " + fragment + " nesting=" + fragment.mBackStackNesting); 1785e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn final boolean inactive = !fragment.isInBackStack(); 1786e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (!fragment.mDetached || inactive) { 1787464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mAdded != null) { 178896221034e4a23a2abb83f772a0281bb197ac5ac0George Mount synchronized (mAdded) { 178996221034e4a23a2abb83f772a0281bb197ac5ac0George Mount mAdded.remove(fragment); 179096221034e4a23a2abb83f772a0281bb197ac5ac0George Mount } 1791464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn } 17922a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn if (fragment.mHasMenu && fragment.mMenuVisible) { 1793e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn mNeedMenuInvalidate = true; 1794e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1795e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn fragment.mAdded = false; 1796e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn fragment.mRemoving = true; 1797cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1798cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1799dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1800990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 1801990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Marks a fragment as hidden to be later animated in with 1802990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@link #completeShowHideFragment(Fragment)}. 1803990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 1804990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param fragment The fragment to be shown. 1805990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 1806990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void hideFragment(Fragment fragment) { 1807cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "hide: " + fragment); 1808cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (!fragment.mHidden) { 1809cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fragment.mHidden = true; 1810990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Toggle hidden changed so that if a fragment goes through show/hide/show 1811990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // it doesn't go through the animation. 1812990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.mHiddenChanged = !fragment.mHiddenChanged; 1813cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1814cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1815dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1816990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 1817990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Marks a fragment as shown to be later animated in with 1818990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@link #completeShowHideFragment(Fragment)}. 1819990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 1820990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param fragment The fragment to be shown. 1821990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 1822990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void showFragment(Fragment fragment) { 1823cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "show: " + fragment); 1824cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (fragment.mHidden) { 1825cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fragment.mHidden = false; 1826990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Toggle hidden changed so that if a fragment goes through show/hide/show 1827990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // it doesn't go through the animation. 1828990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.mHiddenChanged = !fragment.mHiddenChanged; 1829cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1830cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1831dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1832990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void detachFragment(Fragment fragment) { 1833e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (DEBUG) Log.v(TAG, "detach: " + fragment); 1834e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (!fragment.mDetached) { 1835e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn fragment.mDetached = true; 1836e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (fragment.mAdded) { 1837e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn // We are not already in back stack, so need to remove the fragment. 1838464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mAdded != null) { 18393a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn if (DEBUG) Log.v(TAG, "remove from detach: " + fragment); 184096221034e4a23a2abb83f772a0281bb197ac5ac0George Mount synchronized (mAdded) { 184196221034e4a23a2abb83f772a0281bb197ac5ac0George Mount mAdded.remove(fragment); 184296221034e4a23a2abb83f772a0281bb197ac5ac0George Mount } 1843464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn } 18442a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn if (fragment.mHasMenu && fragment.mMenuVisible) { 1845e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn mNeedMenuInvalidate = true; 1846e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1847e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn fragment.mAdded = false; 1848e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1849e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1850e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1851e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn 1852990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void attachFragment(Fragment fragment) { 1853e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (DEBUG) Log.v(TAG, "attach: " + fragment); 1854e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (fragment.mDetached) { 1855e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn fragment.mDetached = false; 1856e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (!fragment.mAdded) { 1857464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mAdded == null) { 1858464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn mAdded = new ArrayList<Fragment>(); 1859464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn } 18603a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn if (mAdded.contains(fragment)) { 18613a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn throw new IllegalStateException("Fragment already added: " + fragment); 18623a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn } 18633a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn if (DEBUG) Log.v(TAG, "add from attach: " + fragment); 186496221034e4a23a2abb83f772a0281bb197ac5ac0George Mount synchronized (mAdded) { 186596221034e4a23a2abb83f772a0281bb197ac5ac0George Mount mAdded.add(fragment); 186696221034e4a23a2abb83f772a0281bb197ac5ac0George Mount } 1867e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn fragment.mAdded = true; 18682a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn if (fragment.mHasMenu && fragment.mMenuVisible) { 1869e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn mNeedMenuInvalidate = true; 1870e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1871e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1872e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1873e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1874e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn 187590ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas @Override 1876cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public Fragment findFragmentById(int id) { 1877464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mAdded != null) { 1878cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // First look through added fragments. 1879cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=mAdded.size()-1; i>=0; i--) { 1880cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mAdded.get(i); 1881cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f != null && f.mFragmentId == id) { 1882cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return f; 1883cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1884cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1885464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn } 1886464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mActive != null) { 1887cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Now for any known fragment. 1888cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=mActive.size()-1; i>=0; i--) { 188990b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount Fragment f = mActive.valueAt(i); 1890cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f != null && f.mFragmentId == id) { 1891cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return f; 1892cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1893cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1894cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1895cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 1896cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 189790ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas 189890ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas @Override 1899cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public Fragment findFragmentByTag(String tag) { 1900464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mAdded != null && tag != null) { 1901cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // First look through added fragments. 1902cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=mAdded.size()-1; i>=0; i--) { 1903cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mAdded.get(i); 1904cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f != null && tag.equals(f.mTag)) { 1905cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return f; 1906cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1907cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1908464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn } 1909464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mActive != null && tag != null) { 1910cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Now for any known fragment. 1911cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=mActive.size()-1; i>=0; i--) { 191290b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount Fragment f = mActive.valueAt(i); 1913cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f != null && tag.equals(f.mTag)) { 1914cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return f; 1915cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1916cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1917cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1918cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 1919cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1920dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1921cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public Fragment findFragmentByWho(String who) { 1922cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mActive != null && who != null) { 1923cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=mActive.size()-1; i>=0; i--) { 192490b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount Fragment f = mActive.valueAt(i); 19250adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (f != null && (f=f.findFragmentByWho(who)) != null) { 1926cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return f; 1927cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1928cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1929cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1930cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 1931cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1932dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1933cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn private void checkStateLoss() { 1934cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mStateSaved) { 1935cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn throw new IllegalStateException( 1936cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn "Can not perform this action after onSaveInstanceState"); 1937cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1938cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mNoTransactionsBecause != null) { 1939cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn throw new IllegalStateException( 1940cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn "Can not perform this action inside of " + mNoTransactionsBecause); 1941cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1942cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1943cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 194447844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount @Override 19455e2b030b851bde2b4569104a01b4acf6960327a6Adam Powell public boolean isStateSaved() { 19465e2b030b851bde2b4569104a01b4acf6960327a6Adam Powell return mStateSaved; 19475e2b030b851bde2b4569104a01b4acf6960327a6Adam Powell } 19485e2b030b851bde2b4569104a01b4acf6960327a6Adam Powell 1949ab6e5dbcc6e05994ebb4257478c54f54085b9aa6Alan Viverette /** 1950ab6e5dbcc6e05994ebb4257478c54f54085b9aa6Alan Viverette * Adds an action to the queue of pending actions. 1951ab6e5dbcc6e05994ebb4257478c54f54085b9aa6Alan Viverette * 1952ab6e5dbcc6e05994ebb4257478c54f54085b9aa6Alan Viverette * @param action the action to add 1953ab6e5dbcc6e05994ebb4257478c54f54085b9aa6Alan Viverette * @param allowStateLoss whether to allow loss of state information 1954ab6e5dbcc6e05994ebb4257478c54f54085b9aa6Alan Viverette * @throws IllegalStateException if the activity has been destroyed 1955ab6e5dbcc6e05994ebb4257478c54f54085b9aa6Alan Viverette */ 1956990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void enqueueAction(OpGenerator action, boolean allowStateLoss) { 1957cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (!allowStateLoss) { 1958cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn checkStateLoss(); 1959cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1960cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn synchronized (this) { 1961d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy if (mDestroyed || mHost == null) { 1962875d9733f354fc93e72c7e8d849c9b5333950183George Mount if (allowStateLoss) { 1963875d9733f354fc93e72c7e8d849c9b5333950183George Mount // This FragmentManager isn't attached, so drop the entire transaction. 1964875d9733f354fc93e72c7e8d849c9b5333950183George Mount return; 1965875d9733f354fc93e72c7e8d849c9b5333950183George Mount } 1966cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn throw new IllegalStateException("Activity has been destroyed"); 1967cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1968cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mPendingActions == null) { 1969990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mPendingActions = new ArrayList<>(); 1970cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1971cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mPendingActions.add(action); 1972990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount scheduleCommit(); 1973990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1974990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1975990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 1976990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 1977990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Schedules the execution when one hasn't been scheduled already. This should happen 1978990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * the first time {@link #enqueueAction(OpGenerator, boolean)} is called or when 1979990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * a postponed transaction has been started with 1980990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@link Fragment#startPostponedEnterTransition()} 1981990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 1982990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void scheduleCommit() { 1983990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount synchronized (this) { 1984990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean postponeReady = 1985990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mPostponedTransactions != null && !mPostponedTransactions.isEmpty(); 1986990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean pendingReady = mPendingActions != null && mPendingActions.size() == 1; 1987990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (postponeReady || pendingReady) { 1988d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy mHost.getHandler().removeCallbacks(mExecCommit); 1989d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy mHost.getHandler().post(mExecCommit); 1990cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1991cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1992cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1993dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1994cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public int allocBackStackIndex(BackStackRecord bse) { 1995cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn synchronized (this) { 1996cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mAvailBackStackIndices == null || mAvailBackStackIndices.size() <= 0) { 1997cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStackIndices == null) { 1998cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackIndices = new ArrayList<BackStackRecord>(); 1999cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2000cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int index = mBackStackIndices.size(); 2001cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Setting back stack index " + index + " to " + bse); 2002cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackIndices.add(bse); 2003cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return index; 2004cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2005cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 2006cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int index = mAvailBackStackIndices.remove(mAvailBackStackIndices.size()-1); 2007cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Adding back stack index " + index + " with " + bse); 2008cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackIndices.set(index, bse); 2009cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return index; 2010cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2011cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2012cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2013cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2014cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void setBackStackIndex(int index, BackStackRecord bse) { 2015cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn synchronized (this) { 2016cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStackIndices == null) { 2017cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackIndices = new ArrayList<BackStackRecord>(); 2018cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2019cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int N = mBackStackIndices.size(); 2020cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (index < N) { 2021cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Setting back stack index " + index + " to " + bse); 2022cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackIndices.set(index, bse); 2023cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 2024cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn while (N < index) { 2025cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackIndices.add(null); 2026cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mAvailBackStackIndices == null) { 2027cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAvailBackStackIndices = new ArrayList<Integer>(); 2028cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2029cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Adding available back stack index " + N); 2030cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAvailBackStackIndices.add(N); 2031cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn N++; 2032cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2033cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Adding back stack index " + index + " with " + bse); 2034cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackIndices.add(bse); 2035cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2036cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2037cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2038cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2039cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void freeBackStackIndex(int index) { 2040cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn synchronized (this) { 2041cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackIndices.set(index, null); 2042cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mAvailBackStackIndices == null) { 2043cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAvailBackStackIndices = new ArrayList<Integer>(); 2044cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2045cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Freeing back stack index " + index); 2046cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAvailBackStackIndices.add(index); 2047cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2048cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2049cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2050990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2051990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Broken out from exec*, this prepares for gathering and executing operations. 2052990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 2053990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param allowStateLoss true if state loss should be ignored or false if it should be 2054990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * checked. 2055990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2056990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void ensureExecReady(boolean allowStateLoss) { 2057e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell if (mExecutingActions) { 2058e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell throw new IllegalStateException("FragmentManager is already executing transactions"); 2059e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell } 2060e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell 2061e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell if (Looper.myLooper() != mHost.getHandler().getLooper()) { 2062e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell throw new IllegalStateException("Must be called from main thread of fragment host"); 2063e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell } 2064e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell 2065e880475b147312ca62bed05bbeb37ec820d693aeAdam Powell if (!allowStateLoss) { 2066e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell checkStateLoss(); 2067e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell } 2068e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell 2069990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mTmpRecords == null) { 2070990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mTmpRecords = new ArrayList<>(); 2071990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mTmpIsPop = new ArrayList<>(); 2072990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 20730a849aafc735476e572e97c78be0ce912adfe512George Mount mExecutingActions = true; 20740a849aafc735476e572e97c78be0ce912adfe512George Mount try { 20750a849aafc735476e572e97c78be0ce912adfe512George Mount executePostponedTransaction(null, null); 20760a849aafc735476e572e97c78be0ce912adfe512George Mount } finally { 20770a849aafc735476e572e97c78be0ce912adfe512George Mount mExecutingActions = false; 20780a849aafc735476e572e97c78be0ce912adfe512George Mount } 2079990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2080990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2081990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void execSingleAction(OpGenerator action, boolean allowStateLoss) { 2082875d9733f354fc93e72c7e8d849c9b5333950183George Mount if (allowStateLoss && (mHost == null || mDestroyed)) { 2083875d9733f354fc93e72c7e8d849c9b5333950183George Mount // This FragmentManager isn't attached, so drop the entire transaction. 2084875d9733f354fc93e72c7e8d849c9b5333950183George Mount return; 2085875d9733f354fc93e72c7e8d849c9b5333950183George Mount } 2086990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ensureExecReady(allowStateLoss); 2087990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (action.generateOps(mTmpRecords, mTmpIsPop)) { 2088990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mExecutingActions = true; 2089990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount try { 2090990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount optimizeAndExecuteOps(mTmpRecords, mTmpIsPop); 2091990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } finally { 2092990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount cleanupExec(); 2093990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2094990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2095e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell 2096e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell doPendingDeferredStart(); 209790b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount burpActive(); 2098e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell } 2099e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell 2100cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 2101990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Broken out of exec*, this cleans up the mExecutingActions and the temporary structures 2102990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * used in executing operations. 2103990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2104990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void cleanupExec() { 2105990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mExecutingActions = false; 2106990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mTmpIsPop.clear(); 2107990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mTmpRecords.clear(); 2108990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2109990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2110990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2111cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Only call from main thread! 2112cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 2113cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean execPendingActions() { 2114990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ensureExecReady(true); 2115990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2116990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean didSomething = false; 2117990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) { 2118990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mExecutingActions = true; 2119990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount try { 2120990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount optimizeAndExecuteOps(mTmpRecords, mTmpIsPop); 2121990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } finally { 2122990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount cleanupExec(); 2123990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2124990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount didSomething = true; 2125cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2126dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2127990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount doPendingDeferredStart(); 212890b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount burpActive(); 2129990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2130990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return didSomething; 2131990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2132990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2133990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2134990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Complete the execution of transactions that have previously been postponed, but are 2135990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * now ready. 2136990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2137990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void executePostponedTransaction(ArrayList<BackStackRecord> records, 2138990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Boolean> isRecordPop) { 2139990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int numPostponed = mPostponedTransactions == null ? 0 : mPostponedTransactions.size(); 2140990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numPostponed; i++) { 2141990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount StartEnterTransitionListener listener = mPostponedTransactions.get(i); 2142990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (records != null && !listener.mIsBack) { 2143990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int index = records.indexOf(listener.mRecord); 2144990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (index != -1 && isRecordPop.get(index)) { 2145990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount listener.cancelTransaction(); 2146990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount continue; 2147990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2148990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2149990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (listener.isReady() || (records != null 2150990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount && listener.mRecord.interactsWith(records, 0, records.size()))) { 2151990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mPostponedTransactions.remove(i); 2152990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount i--; 2153990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount numPostponed--; 2154990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int index; 2155990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (records != null && !listener.mIsBack 2156990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount && (index = records.indexOf(listener.mRecord)) != -1 2157990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount && isRecordPop.get(index)) { 2158990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // This is popping a postponed transaction 2159990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount listener.cancelTransaction(); 2160990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } else { 2161990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount listener.completeTransaction(); 2162990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2163990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2164cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2165990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2166cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2167990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2168990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Optimizes BackStackRecord operations. This method merges operations of proximate records 2169990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * that allow optimization. See {@link FragmentTransaction#setAllowOptimization(boolean)}. 2170990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * <p> 2171990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * For example, a transaction that adds to the back stack and then another that pops that 2172990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * back stack record will be optimized. 2173990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * <p> 2174990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Likewise, two transactions committed that are executed at the same time will be optimized 2175990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * as well as two pop operations executed together. 2176990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 2177990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param records The records pending execution 2178990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param isRecordPop The direction that these records are being run. 2179990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2180990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void optimizeAndExecuteOps(ArrayList<BackStackRecord> records, 2181990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Boolean> isRecordPop) { 2182990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (records == null || records.isEmpty()) { 2183990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return; 2184990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2185990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2186990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (isRecordPop == null || records.size() != isRecordPop.size()) { 2187990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount throw new IllegalStateException("Internal error with the back stack records"); 2188990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2189990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2190990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Force start of any postponed transactions that interact with scheduled transactions: 2191990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount executePostponedTransaction(records, isRecordPop); 2192990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2193990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int numRecords = records.size(); 2194990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int startIndex = 0; 2195990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int recordNum = 0; recordNum < numRecords; recordNum++) { 2196990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final boolean canOptimize = records.get(recordNum).mAllowOptimization; 2197990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (!canOptimize) { 2198990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // execute all previous transactions 2199990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (startIndex != recordNum) { 2200990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount executeOpsTogether(records, isRecordPop, startIndex, recordNum); 2201990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2202f284a0dc76d73ef7132dd1187a43d9a7ad0258deGeorge Mount // execute all unoptimized pop operations together or one add operation 2203f284a0dc76d73ef7132dd1187a43d9a7ad0258deGeorge Mount int optimizeEnd = recordNum + 1; 2204f284a0dc76d73ef7132dd1187a43d9a7ad0258deGeorge Mount if (isRecordPop.get(recordNum)) { 2205f284a0dc76d73ef7132dd1187a43d9a7ad0258deGeorge Mount while (optimizeEnd < numRecords 2206f284a0dc76d73ef7132dd1187a43d9a7ad0258deGeorge Mount && isRecordPop.get(optimizeEnd) 2207f284a0dc76d73ef7132dd1187a43d9a7ad0258deGeorge Mount && !records.get(optimizeEnd).mAllowOptimization) { 2208f284a0dc76d73ef7132dd1187a43d9a7ad0258deGeorge Mount optimizeEnd++; 2209990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2210990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2211990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount executeOpsTogether(records, isRecordPop, recordNum, optimizeEnd); 2212990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount startIndex = optimizeEnd; 2213990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount recordNum = optimizeEnd - 1; 2214990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2215990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2216990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (startIndex != numRecords) { 2217990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount executeOpsTogether(records, isRecordPop, startIndex, numRecords); 2218990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2219990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2220990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2221990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2222990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Optimizes a subset of a list of BackStackRecords, all of which either allow optimization or 2223990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * do not allow optimization. 2224990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param records A list of BackStackRecords that are to be optimized 2225990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param isRecordPop The direction that these records are being run. 2226990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param startIndex The index of the first record in <code>records</code> to be optimized 2227990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param endIndex One more than the final record index in <code>records</code> to optimize. 2228990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2229990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void executeOpsTogether(ArrayList<BackStackRecord> records, 2230990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) { 2231990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final boolean allowOptimization = records.get(startIndex).mAllowOptimization; 2232990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean addToBackStack = false; 2233990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mTmpAddedFragments == null) { 2234990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mTmpAddedFragments = new ArrayList<>(); 2235990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } else { 2236990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mTmpAddedFragments.clear(); 2237990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2238990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mAdded != null) { 2239990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mTmpAddedFragments.addAll(mAdded); 2240990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2241418738949305a8a0e30eba92c125c650048f9c50Adam Powell Fragment oldPrimaryNav = getPrimaryNavigationFragment(); 2242990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int recordNum = startIndex; recordNum < endIndex; recordNum++) { 2243990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final BackStackRecord record = records.get(recordNum); 2244990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final boolean isPop = isRecordPop.get(recordNum); 2245990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (!isPop) { 2246418738949305a8a0e30eba92c125c650048f9c50Adam Powell oldPrimaryNav = record.expandOps(mTmpAddedFragments, oldPrimaryNav); 22471ff374ad7efdabdd103bf0ad3352a4bb184acc78George Mount } else { 22481ff374ad7efdabdd103bf0ad3352a4bb184acc78George Mount oldPrimaryNav = record.trackAddedFragmentsInPop(mTmpAddedFragments, oldPrimaryNav); 2249990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2250990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount addToBackStack = addToBackStack || record.mAddToBackStack; 2251990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2252990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mTmpAddedFragments.clear(); 2253990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2254990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (!allowOptimization) { 2255990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTransition.startTransitions(this, records, isRecordPop, startIndex, endIndex, 2256990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount false); 2257990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2258990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount executeOps(records, isRecordPop, startIndex, endIndex); 2259cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2260990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int postponeIndex = endIndex; 2261990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (allowOptimization) { 22620bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount ArraySet<Fragment> addedFragments = new ArraySet<>(); 22630bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount addAddedFragments(addedFragments); 2264990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount postponeIndex = postponePostponableTransactions(records, isRecordPop, 22650bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount startIndex, endIndex, addedFragments); 22660bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount makeRemovedFragmentsInvisible(addedFragments); 2267990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2268990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2269990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (postponeIndex != startIndex && allowOptimization) { 2270990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // need to run something now 2271990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTransition.startTransitions(this, records, isRecordPop, startIndex, 2272990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount postponeIndex, true); 227377f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount moveToState(mCurState, true); 2274990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2275990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2276990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int recordNum = startIndex; recordNum < endIndex; recordNum++) { 2277990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final BackStackRecord record = records.get(recordNum); 2278990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final boolean isPop = isRecordPop.get(recordNum); 2279990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (isPop && record.mIndex >= 0) { 2280990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount freeBackStackIndex(record.mIndex); 2281990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount record.mIndex = -1; 2282990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 22835e2b030b851bde2b4569104a01b4acf6960327a6Adam Powell record.runOnCommitRunnables(); 2284990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2285990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (addToBackStack) { 2286990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount reportBackStackChanged(); 2287990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2288990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2289dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2290990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 22910bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount * Any fragments that were removed because they have been postponed should have their views 22920bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount * made invisible by setting their alpha to 0 on API >= 11 or setting visibility to INVISIBLE 22930bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount * on API < 11. 22940bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount * 22950bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount * @param fragments The fragments that were added during operation execution. Only the ones 22960bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount * that are no longer added will have their alpha changed. 22970bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount */ 22980bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount private void makeRemovedFragmentsInvisible(ArraySet<Fragment> fragments) { 22990bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount final int numAdded = fragments.size(); 23000bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount for (int i = 0; i < numAdded; i++) { 23010bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount final Fragment fragment = fragments.valueAt(i); 23020bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount if (!fragment.mAdded) { 23030bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount final View view = fragment.getView(); 23049d359be2fec790cf02c3201c89ff37d425d35058Aurimas Liutikas fragment.mPostponedAlpha = view.getAlpha(); 23059d359be2fec790cf02c3201c89ff37d425d35058Aurimas Liutikas view.setAlpha(0f); 23060bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount } 23070bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount } 23080bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount } 23090bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount 23100bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount /** 2311990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Examine all transactions and determine which ones are marked as postponed. Those will 2312990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * have their operations rolled back and moved to the end of the record list (up to endIndex). 2313990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * It will also add the postponed transaction to the queue. 2314990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 2315990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param records A list of BackStackRecords that should be checked. 2316990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param isRecordPop The direction that these records are being run. 2317990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param startIndex The index of the first record in <code>records</code> to be checked 2318990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param endIndex One more than the final record index in <code>records</code> to be checked. 2319990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @return The index of the first postponed transaction or endIndex if no transaction was 2320990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * postponed. 2321990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2322990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private int postponePostponableTransactions(ArrayList<BackStackRecord> records, 23230bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount ArrayList<Boolean> isRecordPop, int startIndex, int endIndex, 23240bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount ArraySet<Fragment> added) { 2325990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int postponeIndex = endIndex; 2326990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = endIndex - 1; i >= startIndex; i--) { 2327990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final BackStackRecord record = records.get(i); 2328990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final boolean isPop = isRecordPop.get(i); 2329990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean isPostponed = record.isPostponed() 2330990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount && !record.interactsWith(records, i + 1, endIndex); 2331990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (isPostponed) { 2332990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mPostponedTransactions == null) { 2333990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mPostponedTransactions = new ArrayList<>(); 2334990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2335990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount StartEnterTransitionListener listener = 2336990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount new StartEnterTransitionListener(record, isPop); 2337990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mPostponedTransactions.add(listener); 2338990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount record.setOnStartPostponedListener(listener); 2339990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2340990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // roll back the transaction 2341990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (isPop) { 2342990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount record.executeOps(); 2343990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } else { 23440846eb5fb991505a85c8288b52d7fa58ebade9b2George Mount record.executePopOps(false); 2345cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2346dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2347990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // move to the end 2348990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount postponeIndex--; 2349990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (i != postponeIndex) { 2350990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount records.remove(i); 2351990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount records.add(postponeIndex, record); 2352cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2353990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2354990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // different views may be visible now 23550bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount addAddedFragments(added); 2356cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2357990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2358990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return postponeIndex; 2359990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2360dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2361990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2362990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * When a postponed transaction is ready to be started, this completes the transaction, 2363990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * removing, hiding, or showing views as well as starting the animations and transitions. 2364990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * <p> 2365990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@code runtransitions} is set to false when the transaction postponement was interrupted 2366990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * abnormally -- normally by a new transaction being started that affects the postponed 2367990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * transaction. 2368990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 2369990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param record The transaction to run 2370990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param isPop true if record is popping or false if it is adding 2371990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param runTransitions true if the fragment transition should be run or false otherwise. 2372990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param moveToState true if the state should be changed after executing the operations. 2373990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * This is false when the transaction is canceled when a postponed 2374990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * transaction is popped. 2375990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2376990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void completeExecute(BackStackRecord record, boolean isPop, boolean runTransitions, 2377990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean moveToState) { 2378990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<BackStackRecord> records = new ArrayList<>(1); 2379990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Boolean> isRecordPop = new ArrayList<>(1); 2380990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount records.add(record); 2381990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount isRecordPop.add(isPop); 2382990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount executeOps(records, isRecordPop, 0, 1); 2383990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (runTransitions) { 2384990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTransition.startTransitions(this, records, isRecordPop, 0, 1, true); 2385990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2386990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (moveToState) { 238777f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount moveToState(mCurState, true); 23880bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount } 23890bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount 23900bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount if (mActive != null) { 2391990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int numActive = mActive.size(); 2392990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numActive; i++) { 2393990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Allow added fragments to be removed during the pop since we aren't going 2394990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // to move them to the final state with moveToState(mCurState). 239590b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount Fragment fragment = mActive.valueAt(i); 23960bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount if (fragment != null && fragment.mView != null && fragment.mIsNewlyAdded 2397990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount && record.interactsWith(fragment.mContainerId)) { 23989d359be2fec790cf02c3201c89ff37d425d35058Aurimas Liutikas if (fragment.mPostponedAlpha > 0) { 23990bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount fragment.mView.setAlpha(fragment.mPostponedAlpha); 24000bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount } 24010bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount if (moveToState) { 24020bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount fragment.mPostponedAlpha = 0; 24030bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount } else { 24040bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount fragment.mPostponedAlpha = -1; 24050bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount fragment.mIsNewlyAdded = false; 24060bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount } 2407990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2408cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2409cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2410990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2411dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2412990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2413990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Find a fragment within the fragment's container whose View should be below the passed 2414990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * fragment. {@code null} is returned when the fragment has no View or if there should be 2415990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * no fragment with a View below the given fragment. 2416990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 2417990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * As an example, if mAdded has two Fragments with Views sharing the same container: 2418990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * FragmentA 2419990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * FragmentB 2420990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 2421990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Then, when processing FragmentB, FragmentA will be returned. If, however, FragmentA 2422990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * had no View, null would be returned. 2423990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 2424990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param f The fragment that may be on top of another fragment. 2425990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @return The fragment with a View under f, if one exists or null if f has no View or 2426990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * there are no fragments with Views in the same container. 2427990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2428990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private Fragment findFragmentUnder(Fragment f) { 2429990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final ViewGroup container = f.mContainer; 2430990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final View view = f.mView; 2431e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell 2432990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (container == null || view == null) { 2433990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return null; 2434990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2435990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2436990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int fragmentIndex = mAdded.indexOf(f); 2437990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = fragmentIndex - 1; i >= 0; i--) { 2438990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Fragment underFragment = mAdded.get(i); 2439990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (underFragment.mContainer == container && underFragment.mView != null) { 2440990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Found the fragment under this one 2441990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return underFragment; 2442990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2443990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2444990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return null; 2445990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2446990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2447990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2448990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Run the operations in the BackStackRecords, either to push or pop. 2449990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 2450990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param records The list of records whose operations should be run. 2451990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param isRecordPop The direction that these records are being run. 2452990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param startIndex The index of the first entry in records to run. 2453990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param endIndex One past the index of the final entry in records to run. 2454990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2455990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private static void executeOps(ArrayList<BackStackRecord> records, 2456990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) { 2457990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = startIndex; i < endIndex; i++) { 2458990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final BackStackRecord record = records.get(i); 2459990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final boolean isPop = isRecordPop.get(i); 2460990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (isPop) { 246137e785570b316db48ae8843d101f383899ea4d61George Mount record.bumpBackStackNesting(-1); 24620846eb5fb991505a85c8288b52d7fa58ebade9b2George Mount // Only execute the add operations at the end of 24630846eb5fb991505a85c8288b52d7fa58ebade9b2George Mount // all transactions. 24640846eb5fb991505a85c8288b52d7fa58ebade9b2George Mount boolean moveToState = i == (endIndex - 1); 24650846eb5fb991505a85c8288b52d7fa58ebade9b2George Mount record.executePopOps(moveToState); 2466990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } else { 246737e785570b316db48ae8843d101f383899ea4d61George Mount record.bumpBackStackNesting(1); 2468990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount record.executeOps(); 2469990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2470990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2471990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2472990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2473990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2474990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Ensure that fragments that are added are moved to at least the CREATED state. 24750bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount * Any newly-added Views are inserted into {@code added} so that the Transaction can be 24760bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount * postponed with {@link Fragment#postponeEnterTransition()}. They will later be made 24770bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount * invisible (by setting their alpha to 0) if they have been removed when postponed. 2478990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 24790bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount private void addAddedFragments(ArraySet<Fragment> added) { 2480990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mCurState < Fragment.CREATED) { 2481990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return; 2482990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2483990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // We want to leave the fragment in the started state 2484990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int state = Math.min(mCurState, Fragment.STARTED); 2485990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int numAdded = mAdded == null ? 0 : mAdded.size(); 2486990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numAdded; i++) { 2487990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Fragment fragment = mAdded.get(i); 2488990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (fragment.mState < state) { 2489990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveToState(fragment, state, fragment.getNextAnim(), fragment.getNextTransition(), 2490990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount false); 2491990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (fragment.mView != null && !fragment.mHidden && fragment.mIsNewlyAdded) { 24920bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount added.add(fragment); 2493990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2494990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2495990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2496990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2497990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2498990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2499990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Starts all postponed transactions regardless of whether they are ready or not. 2500990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2501990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void forcePostponedTransactions() { 2502990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mPostponedTransactions != null) { 2503990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount while (!mPostponedTransactions.isEmpty()) { 2504990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mPostponedTransactions.remove(0).completeTransaction(); 2505990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2506990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2507990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2508990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2509990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2510990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Ends the animations of fragments so that they immediately reach the end state. 2511990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * This is used prior to saving the state so that the correct state is saved. 2512990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2513990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void endAnimatingAwayFragments() { 2514990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int numFragments = mActive == null ? 0 : mActive.size(); 2515990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numFragments; i++) { 251690b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount Fragment fragment = mActive.valueAt(i); 2517990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (fragment != null && fragment.getAnimatingAway() != null) { 2518990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Give up waiting for the animation and just end it. 2519990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int stateAfterAnimating = fragment.getStateAfterAnimating(); 2520990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final View animatingAway = fragment.getAnimatingAway(); 2521990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.setAnimatingAway(null); 25229b07983005689872240dee2084dec3520f95eb5aGeorge Mount Animation animation = animatingAway.getAnimation(); 25239b07983005689872240dee2084dec3520f95eb5aGeorge Mount if (animation != null) { 25249b07983005689872240dee2084dec3520f95eb5aGeorge Mount animation.cancel(); 25259b07983005689872240dee2084dec3520f95eb5aGeorge Mount } 2526990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveToState(fragment, stateAfterAnimating, 0, 0, false); 2527990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2528990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2529990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2530990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2531990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2532990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Adds all records in the pending actions to records and whether they are add or pop 2533990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * operations to isPop. After executing, the pending actions will be empty. 2534990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 2535990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param records All pending actions will generate BackStackRecords added to this. 2536990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * This contains the transactions, in order, to execute. 2537990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param isPop All pending actions will generate booleans to add to this. This contains 2538990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * an entry for each entry in records to indicate whether or not it is a 2539990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * pop action. 2540990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2541990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private boolean generateOpsForPendingActions(ArrayList<BackStackRecord> records, 2542990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Boolean> isPop) { 2543418738949305a8a0e30eba92c125c650048f9c50Adam Powell boolean didSomething = false; 2544990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount synchronized (this) { 2545990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mPendingActions == null || mPendingActions.size() == 0) { 2546990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return false; 2547990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2548990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2549418738949305a8a0e30eba92c125c650048f9c50Adam Powell final int numActions = mPendingActions.size(); 2550990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numActions; i++) { 2551418738949305a8a0e30eba92c125c650048f9c50Adam Powell didSomething |= mPendingActions.get(i).generateOps(records, isPop); 2552990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2553990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mPendingActions.clear(); 2554990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mHost.getHandler().removeCallbacks(mExecCommit); 2555990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2556418738949305a8a0e30eba92c125c650048f9c50Adam Powell return didSomething; 2557e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell } 2558e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell 2559e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell void doPendingDeferredStart() { 256079398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell if (mHavePendingDeferredStart) { 256179398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell boolean loadersRunning = false; 2562e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell for (int i = 0; i < mActive.size(); i++) { 256390b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount Fragment f = mActive.valueAt(i); 256479398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell if (f != null && f.mLoaderManager != null) { 256579398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell loadersRunning |= f.mLoaderManager.hasRunningLoaders(); 256679398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell } 256779398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell } 256879398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell if (!loadersRunning) { 256979398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell mHavePendingDeferredStart = false; 257079398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell startPendingDeferredFragments(); 257179398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell } 257279398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell } 2573cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 257479398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell 2575cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn void reportBackStackChanged() { 2576cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStackChangeListeners != null) { 2577cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<mBackStackChangeListeners.size(); i++) { 2578cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackChangeListeners.get(i).onBackStackChanged(); 2579cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2580cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2581cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2582cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2583cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn void addBackStackState(BackStackRecord state) { 2584cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStack == null) { 2585cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStack = new ArrayList<BackStackRecord>(); 2586cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2587cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStack.add(state); 2588cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn reportBackStackChanged(); 2589cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2590dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2591d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy @SuppressWarnings("unused") 2592990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean popBackStackState(ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop, 2593990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount String name, int id, int flags) { 2594cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStack == null) { 2595cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return false; 2596cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2597990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (name == null && id < 0 && (flags & POP_BACK_STACK_INCLUSIVE) == 0) { 2598990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int last = mBackStack.size() - 1; 2599cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (last < 0) { 2600cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return false; 2601cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2602990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount records.add(mBackStack.remove(last)); 2603990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount isRecordPop.add(true); 2604cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 2605cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int index = -1; 2606cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (name != null || id >= 0) { 2607cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // If a name or ID is specified, look for that place in 2608cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // the stack. 2609cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn index = mBackStack.size()-1; 2610cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn while (index >= 0) { 2611cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn BackStackRecord bss = mBackStack.get(index); 2612cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (name != null && name.equals(bss.getName())) { 2613cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 2614cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2615cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (id >= 0 && id == bss.mIndex) { 2616cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 2617cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2618cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn index--; 2619cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2620cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (index < 0) { 2621cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return false; 2622cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2623cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if ((flags&POP_BACK_STACK_INCLUSIVE) != 0) { 2624cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn index--; 2625cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Consume all following entries that match. 2626cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn while (index >= 0) { 2627cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn BackStackRecord bss = mBackStack.get(index); 2628cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if ((name != null && name.equals(bss.getName())) 2629cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn || (id >= 0 && id == bss.mIndex)) { 2630cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn index--; 2631cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn continue; 2632cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2633cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 2634cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2635cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2636cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2637cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (index == mBackStack.size()-1) { 2638cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return false; 2639cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2640990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = mBackStack.size() - 1; i > index; i--) { 2641990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount records.add(mBackStack.remove(i)); 2642990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount isRecordPop.add(true); 2643cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2644cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2645cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return true; 2646cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2647dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2648c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell FragmentManagerNonConfig retainNonConfig() { 264925806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount setRetaining(mSavedNonConfig); 265025806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount return mSavedNonConfig; 265125806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount } 265225806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount 265325806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount /** 265425806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount * Recurse the FragmentManagerNonConfig fragments and set the mRetaining to true. This 265525806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount * was previously done while saving the non-config state, but that has been moved to 265625806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount * {@link #saveNonConfig()} called from {@link #saveAllState()}. If mRetaining is set too 265725806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount * early, the fragment won't be destroyed when the FragmentManager is destroyed. 265825806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount */ 265925806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount private static void setRetaining(FragmentManagerNonConfig nonConfig) { 266025806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount if (nonConfig == null) { 266125806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount return; 266225806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount } 266325806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount List<Fragment> fragments = nonConfig.getFragments(); 266425806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount if (fragments != null) { 266525806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount for (Fragment fragment : fragments) { 266625806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount fragment.mRetaining = true; 266725806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount } 266825806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount } 266925806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount List<FragmentManagerNonConfig> children = nonConfig.getChildNonConfigs(); 267025806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount if (children != null) { 267125806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount for (FragmentManagerNonConfig child : children) { 267225806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount setRetaining(child); 267325806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount } 267425806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount } 267525806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount } 267625806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount 267725806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount void saveNonConfig() { 2678cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ArrayList<Fragment> fragments = null; 2679c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell ArrayList<FragmentManagerNonConfig> childFragments = null; 2680cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mActive != null) { 2681cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<mActive.size(); i++) { 268290b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount Fragment f = mActive.valueAt(i); 2683c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell if (f != null) { 2684c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell if (f.mRetainInstance) { 2685c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell if (fragments == null) { 2686c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell fragments = new ArrayList<Fragment>(); 2687c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell } 2688c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell fragments.add(f); 2689c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell f.mTargetIndex = f.mTarget != null ? f.mTarget.mIndex : -1; 2690c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell if (DEBUG) Log.v(TAG, "retainNonConfig: keeping retained " + f); 2691c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell } 2692c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell boolean addedChild = false; 2693c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell if (f.mChildFragmentManager != null) { 269425806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount f.mChildFragmentManager.saveNonConfig(); 269525806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount FragmentManagerNonConfig child = f.mChildFragmentManager.mSavedNonConfig; 2696c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell if (child != null) { 2697c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell if (childFragments == null) { 2698c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell childFragments = new ArrayList<FragmentManagerNonConfig>(); 2699c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell for (int j = 0; j < i; j++) { 2700c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell childFragments.add(null); 2701c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell } 2702c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell } 2703c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell childFragments.add(child); 2704c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell addedChild = true; 2705c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell } 2706c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell } 2707c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell if (childFragments != null && !addedChild) { 2708c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell childFragments.add(null); 2709cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2710cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2711cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2712cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2713c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell if (fragments == null && childFragments == null) { 271425806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount mSavedNonConfig = null; 271525806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount } else { 271625806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount mSavedNonConfig = new FragmentManagerNonConfig(fragments, childFragments); 2717c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell } 2718cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2719dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2720cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn void saveFragmentViewState(Fragment f) { 2721cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mInnerView == null) { 2722cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return; 2723cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2724cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mStateArray == null) { 2725cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mStateArray = new SparseArray<Parcelable>(); 2726ea2c91b0198855073983b4a8437aa71cbd83872fDianne Hackborn } else { 2727ea2c91b0198855073983b4a8437aa71cbd83872fDianne Hackborn mStateArray.clear(); 2728cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2729cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mInnerView.saveHierarchyState(mStateArray); 2730cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mStateArray.size() > 0) { 2731cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mSavedViewState = mStateArray; 2732cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mStateArray = null; 2733cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2734cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2735dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 27365c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn Bundle saveFragmentBasicState(Fragment f) { 27375c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn Bundle result = null; 27385c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn 27395c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn if (mStateBundle == null) { 27405c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn mStateBundle = new Bundle(); 27415c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 27420adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.performSaveInstanceState(mStateBundle); 2743267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell dispatchOnFragmentSaveInstanceState(f, mStateBundle, false); 27445c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn if (!mStateBundle.isEmpty()) { 27455c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn result = mStateBundle; 27465c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn mStateBundle = null; 27475c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 27485c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn 27495c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn if (f.mView != null) { 27505c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn saveFragmentViewState(f); 27515c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 27525c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn if (f.mSavedViewState != null) { 27535c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn if (result == null) { 27545c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn result = new Bundle(); 27555c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 27565c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn result.putSparseParcelableArray( 27575c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn FragmentManagerImpl.VIEW_STATE_TAG, f.mSavedViewState); 27585c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 275979398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell if (!f.mUserVisibleHint) { 2760f4c0cf637ba73374a206cec26c09d4dfa4c1a364Jake Wharton if (result == null) { 2761f4c0cf637ba73374a206cec26c09d4dfa4c1a364Jake Wharton result = new Bundle(); 2762f4c0cf637ba73374a206cec26c09d4dfa4c1a364Jake Wharton } 276379398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell // Only add this if it's not the default value 276479398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell result.putBoolean(FragmentManagerImpl.USER_VISIBLE_HINT_TAG, f.mUserVisibleHint); 276579398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell } 27665c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn 27675c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn return result; 27685c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 27695c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn 2770cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Parcelable saveAllState() { 2771cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Make sure all pending operations have now been executed to get 2772cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // our state update-to-date. 2773990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount forcePostponedTransactions(); 2774990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount endAnimatingAwayFragments(); 2775cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn execPendingActions(); 2776cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 27779d359be2fec790cf02c3201c89ff37d425d35058Aurimas Liutikas mStateSaved = true; 277825806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount mSavedNonConfig = null; 2779cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2780cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mActive == null || mActive.size() <= 0) { 2781cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 2782cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2783dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2784cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // First collect all active fragments. 2785cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int N = mActive.size(); 2786cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentState[] active = new FragmentState[N]; 2787cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn boolean haveFragments = false; 2788cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<N; i++) { 278990b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount Fragment f = mActive.valueAt(i); 2790cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f != null) { 27911b913519b1c03b084779851e81db2e1a11eb0b0dDianne Hackborn if (f.mIndex < 0) { 279213fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn throwException(new IllegalStateException( 279313fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn "Failure saving state: active " + f 279413fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn + " has cleared index: " + f.mIndex)); 27951b913519b1c03b084779851e81db2e1a11eb0b0dDianne Hackborn } 27961b913519b1c03b084779851e81db2e1a11eb0b0dDianne Hackborn 2797cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn haveFragments = true; 2798dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2799cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentState fs = new FragmentState(f); 2800cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn active[i] = fs; 2801dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2802cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mState > Fragment.INITIALIZING && fs.mSavedFragmentState == null) { 28035c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn fs.mSavedFragmentState = saveFragmentBasicState(f); 2804cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2805cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mTarget != null) { 2806cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mTarget.mIndex < 0) { 280713fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn throwException(new IllegalStateException( 280813fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn "Failure saving state: " + f 280913fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn + " has target not in fragment manager: " + f.mTarget)); 2810cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2811cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (fs.mSavedFragmentState == null) { 2812cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fs.mSavedFragmentState = new Bundle(); 2813cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2814cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn putFragment(fs.mSavedFragmentState, 2815cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentManagerImpl.TARGET_STATE_TAG, f.mTarget); 2816cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mTargetRequestCode != 0) { 2817cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fs.mSavedFragmentState.putInt( 2818cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 2819cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mTargetRequestCode); 2820cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2821cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2822cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2823cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 2824cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fs.mSavedFragmentState = f.mSavedFragmentState; 2825cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2826dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2827cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Saved state of " + f + ": " 2828cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn + fs.mSavedFragmentState); 2829cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2830cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2831dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2832cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (!haveFragments) { 2833cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "saveAllState: no fragments!"); 2834cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 2835cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2836dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2837cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int[] added = null; 2838cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn BackStackState[] backStack = null; 2839dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2840cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Build list of currently added fragments. 2841cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mAdded != null) { 2842cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn N = mAdded.size(); 2843cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (N > 0) { 2844cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn added = new int[N]; 2845cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<N; i++) { 2846cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn added[i] = mAdded.get(i).mIndex; 28471b913519b1c03b084779851e81db2e1a11eb0b0dDianne Hackborn if (added[i] < 0) { 284813fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn throwException(new IllegalStateException( 284913fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn "Failure saving state: active " + mAdded.get(i) 285013fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn + " has cleared index: " + added[i])); 28511b913519b1c03b084779851e81db2e1a11eb0b0dDianne Hackborn } 2852cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "saveAllState: adding fragment #" + i 2853cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn + ": " + mAdded.get(i)); 2854cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2855cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2856cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2857dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2858cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Now save back stack. 2859cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStack != null) { 2860cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn N = mBackStack.size(); 2861cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (N > 0) { 2862cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn backStack = new BackStackState[N]; 2863cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<N; i++) { 2864d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy backStack[i] = new BackStackState(mBackStack.get(i)); 2865cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "saveAllState: adding back stack #" + i 2866cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn + ": " + mBackStack.get(i)); 2867cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2868cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2869cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2870dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2871cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentManagerState fms = new FragmentManagerState(); 2872cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fms.mActive = active; 2873cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fms.mAdded = added; 2874cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fms.mBackStack = backStack; 2875418738949305a8a0e30eba92c125c650048f9c50Adam Powell if (mPrimaryNav != null) { 2876418738949305a8a0e30eba92c125c650048f9c50Adam Powell fms.mPrimaryNavActiveIndex = mPrimaryNav.mIndex; 2877418738949305a8a0e30eba92c125c650048f9c50Adam Powell } 287890b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount fms.mNextFragmentIndex = mNextFragmentIndex; 287925806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount saveNonConfig(); 2880cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return fms; 2881cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2882dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2883c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell void restoreAllState(Parcelable state, FragmentManagerNonConfig nonConfig) { 2884cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // If there is no saved state at all, then there can not be 2885cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // any nonConfig fragments either, so that is that. 2886cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (state == null) return; 2887cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentManagerState fms = (FragmentManagerState)state; 2888cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (fms.mActive == null) return; 2889c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell 2890c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell List<FragmentManagerNonConfig> childNonConfigs = null; 2891c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell 2892cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // First re-attach any non-config instances we are retaining back 2893cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // to their saved state, so we don't try to instantiate them again. 2894cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (nonConfig != null) { 2895c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell List<Fragment> nonConfigFragments = nonConfig.getFragments(); 2896c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell childNonConfigs = nonConfig.getChildNonConfigs(); 2897c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell final int count = nonConfigFragments != null ? nonConfigFragments.size() : 0; 2898c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell for (int i = 0; i < count; i++) { 2899c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell Fragment f = nonConfigFragments.get(i); 2900cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "restoreAllState: re-attaching retained " + f); 290138083235ff15c516dbba4ef655f4895b0282cf7bGeorge Mount int index = 0; // index into fms.mActive 290238083235ff15c516dbba4ef655f4895b0282cf7bGeorge Mount while (index < fms.mActive.length && fms.mActive[index].mIndex != f.mIndex) { 290338083235ff15c516dbba4ef655f4895b0282cf7bGeorge Mount index++; 290438083235ff15c516dbba4ef655f4895b0282cf7bGeorge Mount } 290538083235ff15c516dbba4ef655f4895b0282cf7bGeorge Mount if (index == fms.mActive.length) { 290638083235ff15c516dbba4ef655f4895b0282cf7bGeorge Mount throwException(new IllegalStateException("Could not find active fragment " 290738083235ff15c516dbba4ef655f4895b0282cf7bGeorge Mount + "with index " + f.mIndex)); 290838083235ff15c516dbba4ef655f4895b0282cf7bGeorge Mount } 290938083235ff15c516dbba4ef655f4895b0282cf7bGeorge Mount FragmentState fs = fms.mActive[index]; 2910cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fs.mInstance = f; 2911cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mSavedViewState = null; 2912cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mBackStackNesting = 0; 2913cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mInLayout = false; 2914cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mAdded = false; 29152c4b5dbfee5232bcbbcb74b84ce9147b62a9d789Dianne Hackborn f.mTarget = null; 2916cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (fs.mSavedFragmentState != null) { 2917d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy fs.mSavedFragmentState.setClassLoader(mHost.getContext().getClassLoader()); 2918cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mSavedViewState = fs.mSavedFragmentState.getSparseParcelableArray( 2919cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentManagerImpl.VIEW_STATE_TAG); 29208e4a59b54e9225b77151805dd6b8867dcd8e60a4Craig Mautner f.mSavedFragmentState = fs.mSavedFragmentState; 2921cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2922cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2923cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2924dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2925cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Build the full list of active fragments, instantiating them from 2926cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // their saved state. 292790b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount mActive = new SparseArray<>(fms.mActive.length); 2928cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<fms.mActive.length; i++) { 2929cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentState fs = fms.mActive[i]; 2930cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (fs != null) { 2931c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell FragmentManagerNonConfig childNonConfig = null; 2932c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell if (childNonConfigs != null && i < childNonConfigs.size()) { 2933c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell childNonConfig = childNonConfigs.get(i); 2934c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell } 29354aebb5be19bbf9314e7474dd62df8dd915313436Adam Powell Fragment f = fs.instantiate(mHost, mContainer, mParent, childNonConfig); 29363a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn if (DEBUG) Log.v(TAG, "restoreAllState: active #" + i + ": " + f); 293790b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount mActive.put(f.mIndex, f); 2938cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Now that the fragment is instantiated (or came from being 2939cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // retained above), clear mInstance in case we end up re-restoring 2940cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // from this FragmentState again. 2941cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fs.mInstance = null; 2942cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2943cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2944dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2945cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Update the target of all retained fragments. 2946cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (nonConfig != null) { 2947c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell List<Fragment> nonConfigFragments = nonConfig.getFragments(); 2948c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell final int count = nonConfigFragments != null ? nonConfigFragments.size() : 0; 2949c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell for (int i = 0; i < count; i++) { 2950c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell Fragment f = nonConfigFragments.get(i); 29512c4b5dbfee5232bcbbcb74b84ce9147b62a9d789Dianne Hackborn if (f.mTargetIndex >= 0) { 295290b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount f.mTarget = mActive.get(f.mTargetIndex); 295390b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount if (f.mTarget == null) { 2954cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Log.w(TAG, "Re-attaching retained fragment " + f 29552c4b5dbfee5232bcbbcb74b84ce9147b62a9d789Dianne Hackborn + " target no longer exists: " + f.mTargetIndex); 2956cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2957cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2958cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2959cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2960cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2961cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Build the list of currently added fragments. 2962cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (fms.mAdded != null) { 2963cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAdded = new ArrayList<Fragment>(fms.mAdded.length); 2964cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<fms.mAdded.length; i++) { 2965cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mActive.get(fms.mAdded[i]); 2966cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f == null) { 296713fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn throwException(new IllegalStateException( 296813fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn "No instantiated fragment for index #" + fms.mAdded[i])); 2969cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2970cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mAdded = true; 29713a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn if (DEBUG) Log.v(TAG, "restoreAllState: added #" + i + ": " + f); 29723a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn if (mAdded.contains(f)) { 29733a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn throw new IllegalStateException("Already added!"); 29743a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn } 297596221034e4a23a2abb83f772a0281bb197ac5ac0George Mount synchronized (mAdded) { 297696221034e4a23a2abb83f772a0281bb197ac5ac0George Mount mAdded.add(f); 297796221034e4a23a2abb83f772a0281bb197ac5ac0George Mount } 2978cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2979cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 2980cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAdded = null; 2981cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2982dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2983cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Build the back stack. 2984cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (fms.mBackStack != null) { 2985cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStack = new ArrayList<BackStackRecord>(fms.mBackStack.length); 2986cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<fms.mBackStack.length; i++) { 2987cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn BackStackRecord bse = fms.mBackStack[i].instantiate(this); 29883a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn if (DEBUG) { 29893a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn Log.v(TAG, "restoreAllState: back stack #" + i 2990cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn + " (index " + bse.mIndex + "): " + bse); 29913a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn LogWriter logw = new LogWriter(TAG); 29923a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn PrintWriter pw = new PrintWriter(logw); 29933a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn bse.dump(" ", pw, false); 2994f83358389f0c4ea37a7e7d9e493857f99baf0440Chris Banes pw.close(); 29953a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn } 2996cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStack.add(bse); 2997cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (bse.mIndex >= 0) { 2998cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn setBackStackIndex(bse.mIndex, bse); 2999cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3000cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3001cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 3002cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStack = null; 3003cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3004418738949305a8a0e30eba92c125c650048f9c50Adam Powell 3005418738949305a8a0e30eba92c125c650048f9c50Adam Powell if (fms.mPrimaryNavActiveIndex >= 0) { 3006418738949305a8a0e30eba92c125c650048f9c50Adam Powell mPrimaryNav = mActive.get(fms.mPrimaryNavActiveIndex); 3007418738949305a8a0e30eba92c125c650048f9c50Adam Powell } 300890b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount this.mNextFragmentIndex = fms.mNextFragmentIndex; 300990b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount } 301090b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount 301190b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount /** 301290b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount * To prevent list modification errors, mActive sets values to null instead of 301390b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount * removing them when the Fragment becomes inactive. This cleans up the list at the 301490b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount * end of executing the transactions. 301590b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount */ 301690b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount private void burpActive() { 301790b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount if (mActive != null) { 301890b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount for (int i = mActive.size() - 1; i >= 0; i--) { 301990b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount if (mActive.valueAt(i) == null) { 302090b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount mActive.delete(mActive.keyAt(i)); 302190b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount } 302290b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount } 302390b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount } 3024cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3025d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy 30268491eb62f621cd5de4b4caed839be09c77011f53Todd Kennedy public void attachController(FragmentHostCallback host, 30270adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn FragmentContainer container, Fragment parent) { 3028d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy if (mHost != null) throw new IllegalStateException("Already attached"); 3029d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy mHost = host; 30300adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn mContainer = container; 30310adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn mParent = parent; 3032cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3033dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3034cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void noteStateNotSaved() { 303525806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount mSavedNonConfig = null; 3036cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mStateSaved = false; 30370765353c002bfdf681c982565810aa4be3499dd0George Mount final int addedCount = mAdded == null ? 0 : mAdded.size(); 30380765353c002bfdf681c982565810aa4be3499dd0George Mount for (int i = 0; i < addedCount; i++) { 30390765353c002bfdf681c982565810aa4be3499dd0George Mount Fragment fragment = mAdded.get(i); 30400765353c002bfdf681c982565810aa4be3499dd0George Mount if (fragment != null) { 30410765353c002bfdf681c982565810aa4be3499dd0George Mount fragment.noteStateNotSaved(); 30420765353c002bfdf681c982565810aa4be3499dd0George Mount } 30430765353c002bfdf681c982565810aa4be3499dd0George Mount } 3044cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3045dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3046cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchCreate() { 3047cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mStateSaved = false; 30489268ce1264c6c2919b3feb1e26eef13ded3c9ab4George Mount mExecutingActions = true; 304977f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount moveToState(Fragment.CREATED, false); 30509268ce1264c6c2919b3feb1e26eef13ded3c9ab4George Mount mExecutingActions = false; 3051cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3052dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3053cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchActivityCreated() { 3054cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mStateSaved = false; 30559268ce1264c6c2919b3feb1e26eef13ded3c9ab4George Mount mExecutingActions = true; 305677f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount moveToState(Fragment.ACTIVITY_CREATED, false); 30579268ce1264c6c2919b3feb1e26eef13ded3c9ab4George Mount mExecutingActions = false; 3058cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3059dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3060cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchStart() { 3061cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mStateSaved = false; 30629268ce1264c6c2919b3feb1e26eef13ded3c9ab4George Mount mExecutingActions = true; 306377f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount moveToState(Fragment.STARTED, false); 30649268ce1264c6c2919b3feb1e26eef13ded3c9ab4George Mount mExecutingActions = false; 3065cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3066dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3067cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchResume() { 3068cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mStateSaved = false; 30699268ce1264c6c2919b3feb1e26eef13ded3c9ab4George Mount mExecutingActions = true; 307077f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount moveToState(Fragment.RESUMED, false); 30719268ce1264c6c2919b3feb1e26eef13ded3c9ab4George Mount mExecutingActions = false; 3072cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3073dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3074cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchPause() { 30759268ce1264c6c2919b3feb1e26eef13ded3c9ab4George Mount mExecutingActions = true; 307677f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount moveToState(Fragment.STARTED, false); 30779268ce1264c6c2919b3feb1e26eef13ded3c9ab4George Mount mExecutingActions = false; 3078cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3079dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3080cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchStop() { 3081681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn // See saveAllState() for the explanation of this. We do this for 3082681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn // all platform versions, to keep our behavior more consistent between 3083681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn // them. 3084681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn mStateSaved = true; 3085681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn 30869268ce1264c6c2919b3feb1e26eef13ded3c9ab4George Mount mExecutingActions = true; 308777f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount moveToState(Fragment.STOPPED, false); 30889268ce1264c6c2919b3feb1e26eef13ded3c9ab4George Mount mExecutingActions = false; 3089cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3090dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3091218c1e661578e2a17928f7dbb590b43d1c79aeb7Dianne Hackborn public void dispatchReallyStop() { 30929268ce1264c6c2919b3feb1e26eef13ded3c9ab4George Mount mExecutingActions = true; 309377f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount moveToState(Fragment.ACTIVITY_CREATED, false); 30949268ce1264c6c2919b3feb1e26eef13ded3c9ab4George Mount mExecutingActions = false; 3095681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn } 3096681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn 30970adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn public void dispatchDestroyView() { 30989268ce1264c6c2919b3feb1e26eef13ded3c9ab4George Mount mExecutingActions = true; 309977f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount moveToState(Fragment.CREATED, false); 31009268ce1264c6c2919b3feb1e26eef13ded3c9ab4George Mount mExecutingActions = false; 31010adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn } 31020adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn 3103cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchDestroy() { 3104cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mDestroyed = true; 3105e8b402b00c0cbdac050c349a5fc89c34580f3185Dianne Hackborn execPendingActions(); 31069268ce1264c6c2919b3feb1e26eef13ded3c9ab4George Mount mExecutingActions = true; 310777f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount moveToState(Fragment.INITIALIZING, false); 31089268ce1264c6c2919b3feb1e26eef13ded3c9ab4George Mount mExecutingActions = false; 3109d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy mHost = null; 31100adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn mContainer = null; 31110adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn mParent = null; 3112cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 31135fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian 31145fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian public void dispatchMultiWindowModeChanged(boolean isInMultiWindowMode) { 31155fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian if (mAdded == null) { 31165fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian return; 31175fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian } 31185fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian for (int i = mAdded.size() - 1; i >= 0; --i) { 31195fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian final android.support.v4.app.Fragment f = mAdded.get(i); 31205fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian if (f != null) { 31215fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian f.performMultiWindowModeChanged(isInMultiWindowMode); 31225fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian } 31235fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian } 31245fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian } 31255fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian 31265fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian public void dispatchPictureInPictureModeChanged(boolean isInPictureInPictureMode) { 31275fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian if (mAdded == null) { 31285fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian return; 31295fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian } 31305fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian for (int i = mAdded.size() - 1; i >= 0; --i) { 31315fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian final android.support.v4.app.Fragment f = mAdded.get(i); 31325fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian if (f != null) { 31335fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian f.performPictureInPictureModeChanged(isInPictureInPictureMode); 31345fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian } 31355fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian } 31365fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian } 31375fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian 3138cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchConfigurationChanged(Configuration newConfig) { 3139464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mAdded != null) { 3140cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<mAdded.size(); i++) { 3141cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mAdded.get(i); 3142cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f != null) { 31430adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.performConfigurationChanged(newConfig); 3144cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3145cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3146cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3147cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3148cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 3149cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchLowMemory() { 3150464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mAdded != null) { 3151cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<mAdded.size(); i++) { 3152cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mAdded.get(i); 3153cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f != null) { 31540adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.performLowMemory(); 3155cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3156cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3157cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3158cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3159cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 3160cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean dispatchCreateOptionsMenu(Menu menu, MenuInflater inflater) { 3161cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn boolean show = false; 3162cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ArrayList<Fragment> newMenus = null; 3163464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mAdded != null) { 3164cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<mAdded.size(); i++) { 3165cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mAdded.get(i); 31660adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (f != null) { 31670adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (f.performCreateOptionsMenu(menu, inflater)) { 31680adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn show = true; 31690adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (newMenus == null) { 31700adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn newMenus = new ArrayList<Fragment>(); 31710adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn } 31720adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn newMenus.add(f); 3173cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3174cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3175cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3176cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3177c1e87ac17c772ee3c5fd3b3f08321226e2c7ffa4Chris Banes 3178cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mCreatedMenus != null) { 3179cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<mCreatedMenus.size(); i++) { 3180cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mCreatedMenus.get(i); 3181cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (newMenus == null || !newMenus.contains(f)) { 3182cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.onDestroyOptionsMenu(); 3183cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3184cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3185cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3186c1e87ac17c772ee3c5fd3b3f08321226e2c7ffa4Chris Banes 3187cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mCreatedMenus = newMenus; 3188c1e87ac17c772ee3c5fd3b3f08321226e2c7ffa4Chris Banes 3189cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return show; 3190cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3191dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3192cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean dispatchPrepareOptionsMenu(Menu menu) { 3193cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn boolean show = false; 3194464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mAdded != null) { 3195cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<mAdded.size(); i++) { 3196cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mAdded.get(i); 31970adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (f != null) { 31980adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (f.performPrepareOptionsMenu(menu)) { 31990adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn show = true; 32000adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn } 3201cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3202cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3203cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3204cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return show; 3205cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3206dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3207cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean dispatchOptionsItemSelected(MenuItem item) { 3208464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mAdded != null) { 3209cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<mAdded.size(); i++) { 3210cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mAdded.get(i); 32110adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (f != null) { 32120adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (f.performOptionsItemSelected(item)) { 3213cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return true; 3214cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3215cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3216cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3217cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3218cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return false; 3219cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3220dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3221cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean dispatchContextItemSelected(MenuItem item) { 3222464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mAdded != null) { 3223cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<mAdded.size(); i++) { 3224cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mAdded.get(i); 32250adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (f != null) { 32260adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (f.performContextItemSelected(item)) { 3227cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return true; 3228cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3229cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3230cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3231cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3232cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return false; 3233cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3234dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3235cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchOptionsMenuClosed(Menu menu) { 3236464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mAdded != null) { 3237cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<mAdded.size(); i++) { 3238cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mAdded.get(i); 32390adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (f != null) { 32400adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.performOptionsMenuClosed(menu); 3241cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3242cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3243cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3244cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3245461b48b4588ac21b97aa40553f04222c2c0344e7Chris Banes 3246418738949305a8a0e30eba92c125c650048f9c50Adam Powell public void setPrimaryNavigationFragment(Fragment f) { 324796767975440de77e44a231e6ef66b374b1403bd0George Mount if (f != null && (mActive.get(f.mIndex) != f 324896767975440de77e44a231e6ef66b374b1403bd0George Mount || (f.mHost != null && f.getFragmentManager() != this))) { 3249418738949305a8a0e30eba92c125c650048f9c50Adam Powell throw new IllegalArgumentException("Fragment " + f 3250418738949305a8a0e30eba92c125c650048f9c50Adam Powell + " is not an active fragment of FragmentManager " + this); 3251418738949305a8a0e30eba92c125c650048f9c50Adam Powell } 3252418738949305a8a0e30eba92c125c650048f9c50Adam Powell mPrimaryNav = f; 3253418738949305a8a0e30eba92c125c650048f9c50Adam Powell } 3254418738949305a8a0e30eba92c125c650048f9c50Adam Powell 3255e2104f4b5c8e3ad63570306a25e61502dfe4c418Aurimas Liutikas @Override 3256418738949305a8a0e30eba92c125c650048f9c50Adam Powell public Fragment getPrimaryNavigationFragment() { 3257418738949305a8a0e30eba92c125c650048f9c50Adam Powell return mPrimaryNav; 3258418738949305a8a0e30eba92c125c650048f9c50Adam Powell } 3259418738949305a8a0e30eba92c125c650048f9c50Adam Powell 3260e2104f4b5c8e3ad63570306a25e61502dfe4c418Aurimas Liutikas @Override 3261267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell public void registerFragmentLifecycleCallbacks(FragmentLifecycleCallbacks cb, 3262267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell boolean recursive) { 3263267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mLifecycleCallbacks == null) { 3264267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell mLifecycleCallbacks = new CopyOnWriteArrayList<>(); 3265267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3266abc73958d264e1eed7fd401a18be1d9ede8304ebAurimas Liutikas mLifecycleCallbacks.add(new Pair<>(cb, recursive)); 3267267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3268267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3269e2104f4b5c8e3ad63570306a25e61502dfe4c418Aurimas Liutikas @Override 3270267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell public void unregisterFragmentLifecycleCallbacks(FragmentLifecycleCallbacks cb) { 3271267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mLifecycleCallbacks == null) { 3272267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell return; 3273267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3274267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3275267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell synchronized (mLifecycleCallbacks) { 3276267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell for (int i = 0, N = mLifecycleCallbacks.size(); i < N; i++) { 3277267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mLifecycleCallbacks.get(i).first == cb) { 3278267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell mLifecycleCallbacks.remove(i); 3279267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell break; 3280267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3281267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3282267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3283267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3284267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3285267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell void dispatchOnFragmentPreAttached(Fragment f, Context context, boolean onlyRecursive) { 3286267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mParent != null) { 3287267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell FragmentManager parentManager = mParent.getFragmentManager(); 3288267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (parentManager instanceof FragmentManagerImpl) { 3289267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell ((FragmentManagerImpl) parentManager) 3290267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell .dispatchOnFragmentPreAttached(f, context, true); 3291267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3292267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3293267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mLifecycleCallbacks == null) { 3294267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell return; 3295267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3296267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell for (Pair<FragmentLifecycleCallbacks, Boolean> p : mLifecycleCallbacks) { 3297267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (!onlyRecursive || p.second) { 3298267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell p.first.onFragmentPreAttached(this, f, context); 3299267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3300267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3301267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3302267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3303267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell void dispatchOnFragmentAttached(Fragment f, Context context, boolean onlyRecursive) { 3304267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mParent != null) { 3305267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell FragmentManager parentManager = mParent.getFragmentManager(); 3306267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (parentManager instanceof FragmentManagerImpl) { 3307267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell ((FragmentManagerImpl) parentManager) 3308267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell .dispatchOnFragmentAttached(f, context, true); 3309267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3310267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3311267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mLifecycleCallbacks == null) { 3312267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell return; 3313267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3314267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell for (Pair<FragmentLifecycleCallbacks, Boolean> p : mLifecycleCallbacks) { 3315267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (!onlyRecursive || p.second) { 3316267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell p.first.onFragmentAttached(this, f, context); 3317267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3318267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3319267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3320267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3321267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell void dispatchOnFragmentCreated(Fragment f, Bundle savedInstanceState, boolean onlyRecursive) { 3322267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mParent != null) { 3323267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell FragmentManager parentManager = mParent.getFragmentManager(); 3324267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (parentManager instanceof FragmentManagerImpl) { 3325267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell ((FragmentManagerImpl) parentManager) 3326267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell .dispatchOnFragmentCreated(f, savedInstanceState, true); 3327267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3328267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3329267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mLifecycleCallbacks == null) { 3330267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell return; 3331267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3332267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell for (Pair<FragmentLifecycleCallbacks, Boolean> p : mLifecycleCallbacks) { 3333267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (!onlyRecursive || p.second) { 3334267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell p.first.onFragmentCreated(this, f, savedInstanceState); 3335267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3336267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3337267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3338267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3339267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell void dispatchOnFragmentActivityCreated(Fragment f, Bundle savedInstanceState, 3340267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell boolean onlyRecursive) { 3341267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mParent != null) { 3342267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell FragmentManager parentManager = mParent.getFragmentManager(); 3343267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (parentManager instanceof FragmentManagerImpl) { 3344267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell ((FragmentManagerImpl) parentManager) 3345267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell .dispatchOnFragmentActivityCreated(f, savedInstanceState, true); 3346267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3347267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3348267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mLifecycleCallbacks == null) { 3349267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell return; 3350267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3351267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell for (Pair<FragmentLifecycleCallbacks, Boolean> p : mLifecycleCallbacks) { 3352267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (!onlyRecursive || p.second) { 3353267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell p.first.onFragmentActivityCreated(this, f, savedInstanceState); 3354267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3355267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3356267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3357267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3358267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell void dispatchOnFragmentViewCreated(Fragment f, View v, Bundle savedInstanceState, 3359267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell boolean onlyRecursive) { 3360267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mParent != null) { 3361267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell FragmentManager parentManager = mParent.getFragmentManager(); 3362267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (parentManager instanceof FragmentManagerImpl) { 3363267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell ((FragmentManagerImpl) parentManager) 3364267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell .dispatchOnFragmentViewCreated(f, v, savedInstanceState, true); 3365267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3366267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3367267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mLifecycleCallbacks == null) { 3368267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell return; 3369267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3370267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell for (Pair<FragmentLifecycleCallbacks, Boolean> p : mLifecycleCallbacks) { 3371267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (!onlyRecursive || p.second) { 3372267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell p.first.onFragmentViewCreated(this, f, v, savedInstanceState); 3373267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3374267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3375267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3376267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3377267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell void dispatchOnFragmentStarted(Fragment f, boolean onlyRecursive) { 3378267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mParent != null) { 3379267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell FragmentManager parentManager = mParent.getFragmentManager(); 3380267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (parentManager instanceof FragmentManagerImpl) { 3381267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell ((FragmentManagerImpl) parentManager) 3382267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell .dispatchOnFragmentStarted(f, true); 3383267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3384267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3385267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mLifecycleCallbacks == null) { 3386267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell return; 3387267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3388267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell for (Pair<FragmentLifecycleCallbacks, Boolean> p : mLifecycleCallbacks) { 3389267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (!onlyRecursive || p.second) { 3390267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell p.first.onFragmentStarted(this, f); 3391267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3392267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3393267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3394267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3395267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell void dispatchOnFragmentResumed(Fragment f, boolean onlyRecursive) { 3396267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mParent != null) { 3397267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell FragmentManager parentManager = mParent.getFragmentManager(); 3398267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (parentManager instanceof FragmentManagerImpl) { 3399267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell ((FragmentManagerImpl) parentManager) 3400267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell .dispatchOnFragmentResumed(f, true); 3401267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3402267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3403267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mLifecycleCallbacks == null) { 3404267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell return; 3405267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3406267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell for (Pair<FragmentLifecycleCallbacks, Boolean> p : mLifecycleCallbacks) { 3407267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (!onlyRecursive || p.second) { 3408267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell p.first.onFragmentResumed(this, f); 3409267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3410267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3411267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3412267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3413267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell void dispatchOnFragmentPaused(Fragment f, boolean onlyRecursive) { 3414267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mParent != null) { 3415267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell FragmentManager parentManager = mParent.getFragmentManager(); 3416267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (parentManager instanceof FragmentManagerImpl) { 3417267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell ((FragmentManagerImpl) parentManager) 3418267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell .dispatchOnFragmentPaused(f, true); 3419267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3420267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3421267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mLifecycleCallbacks == null) { 3422267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell return; 3423267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3424267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell for (Pair<FragmentLifecycleCallbacks, Boolean> p : mLifecycleCallbacks) { 3425267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (!onlyRecursive || p.second) { 3426267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell p.first.onFragmentPaused(this, f); 3427267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3428267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3429267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3430267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3431267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell void dispatchOnFragmentStopped(Fragment f, boolean onlyRecursive) { 3432267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mParent != null) { 3433267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell FragmentManager parentManager = mParent.getFragmentManager(); 3434267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (parentManager instanceof FragmentManagerImpl) { 3435267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell ((FragmentManagerImpl) parentManager) 3436267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell .dispatchOnFragmentStopped(f, true); 3437267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3438267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3439267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mLifecycleCallbacks == null) { 3440267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell return; 3441267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3442267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell for (Pair<FragmentLifecycleCallbacks, Boolean> p : mLifecycleCallbacks) { 3443267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (!onlyRecursive || p.second) { 3444267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell p.first.onFragmentStopped(this, f); 3445267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3446267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3447267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3448267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3449267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell void dispatchOnFragmentSaveInstanceState(Fragment f, Bundle outState, boolean onlyRecursive) { 3450267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mParent != null) { 3451267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell FragmentManager parentManager = mParent.getFragmentManager(); 3452267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (parentManager instanceof FragmentManagerImpl) { 3453267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell ((FragmentManagerImpl) parentManager) 3454267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell .dispatchOnFragmentSaveInstanceState(f, outState, true); 3455267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3456267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3457267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mLifecycleCallbacks == null) { 3458267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell return; 3459267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3460267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell for (Pair<FragmentLifecycleCallbacks, Boolean> p : mLifecycleCallbacks) { 3461267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (!onlyRecursive || p.second) { 3462267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell p.first.onFragmentSaveInstanceState(this, f, outState); 3463267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3464267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3465267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3466267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3467267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell void dispatchOnFragmentViewDestroyed(Fragment f, boolean onlyRecursive) { 3468267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mParent != null) { 3469267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell FragmentManager parentManager = mParent.getFragmentManager(); 3470267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (parentManager instanceof FragmentManagerImpl) { 3471267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell ((FragmentManagerImpl) parentManager) 3472267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell .dispatchOnFragmentViewDestroyed(f, true); 3473267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3474267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3475267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mLifecycleCallbacks == null) { 3476267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell return; 3477267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3478267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell for (Pair<FragmentLifecycleCallbacks, Boolean> p : mLifecycleCallbacks) { 3479267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (!onlyRecursive || p.second) { 3480267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell p.first.onFragmentViewDestroyed(this, f); 3481267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3482267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3483267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3484267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3485267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell void dispatchOnFragmentDestroyed(Fragment f, boolean onlyRecursive) { 3486267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mParent != null) { 3487267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell FragmentManager parentManager = mParent.getFragmentManager(); 3488267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (parentManager instanceof FragmentManagerImpl) { 3489267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell ((FragmentManagerImpl) parentManager) 3490267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell .dispatchOnFragmentDestroyed(f, true); 3491267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3492267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3493267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mLifecycleCallbacks == null) { 3494267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell return; 3495267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3496267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell for (Pair<FragmentLifecycleCallbacks, Boolean> p : mLifecycleCallbacks) { 3497267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (!onlyRecursive || p.second) { 3498267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell p.first.onFragmentDestroyed(this, f); 3499267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3500267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3501267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3502267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3503267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell void dispatchOnFragmentDetached(Fragment f, boolean onlyRecursive) { 3504267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mParent != null) { 3505267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell FragmentManager parentManager = mParent.getFragmentManager(); 3506267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (parentManager instanceof FragmentManagerImpl) { 3507267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell ((FragmentManagerImpl) parentManager) 3508267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell .dispatchOnFragmentDetached(f, true); 3509267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3510267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3511267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mLifecycleCallbacks == null) { 3512267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell return; 3513267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3514267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell for (Pair<FragmentLifecycleCallbacks, Boolean> p : mLifecycleCallbacks) { 3515267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (!onlyRecursive || p.second) { 3516267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell p.first.onFragmentDetached(this, f); 3517267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3518267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3519267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3520267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3521cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public static int reverseTransit(int transit) { 3522cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int rev = 0; 3523cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn switch (transit) { 3524cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case FragmentTransaction.TRANSIT_FRAGMENT_OPEN: 3525cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn rev = FragmentTransaction.TRANSIT_FRAGMENT_CLOSE; 3526cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 3527cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case FragmentTransaction.TRANSIT_FRAGMENT_CLOSE: 3528cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn rev = FragmentTransaction.TRANSIT_FRAGMENT_OPEN; 3529cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 3530cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case FragmentTransaction.TRANSIT_FRAGMENT_FADE: 3531cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn rev = FragmentTransaction.TRANSIT_FRAGMENT_FADE; 3532cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 3533cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3534cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return rev; 3535dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3536cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3537dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 35389277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn public static final int ANIM_STYLE_OPEN_ENTER = 1; 35399277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn public static final int ANIM_STYLE_OPEN_EXIT = 2; 35409277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn public static final int ANIM_STYLE_CLOSE_ENTER = 3; 35419277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn public static final int ANIM_STYLE_CLOSE_EXIT = 4; 35429277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn public static final int ANIM_STYLE_FADE_ENTER = 5; 35439277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn public static final int ANIM_STYLE_FADE_EXIT = 6; 3544dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3545cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public static int transitToStyleIndex(int transit, boolean enter) { 3546cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int animAttr = -1; 3547cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn switch (transit) { 3548cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case FragmentTransaction.TRANSIT_FRAGMENT_OPEN: 35499277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn animAttr = enter ? ANIM_STYLE_OPEN_ENTER : ANIM_STYLE_OPEN_EXIT; 3550cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 3551cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case FragmentTransaction.TRANSIT_FRAGMENT_CLOSE: 35529277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn animAttr = enter ? ANIM_STYLE_CLOSE_ENTER : ANIM_STYLE_CLOSE_EXIT; 3553cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 3554cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case FragmentTransaction.TRANSIT_FRAGMENT_FADE: 35559277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn animAttr = enter ? ANIM_STYLE_FADE_ENTER : ANIM_STYLE_FADE_EXIT; 3556cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 3557cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3558cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return animAttr; 3559cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 35600f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 35610f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell @Override 3562bf0947be2ead9b3d8e5865bcd3d3652d02a2aa5aChris Banes public View onCreateView(View parent, String name, Context context, AttributeSet attrs) { 35630f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (!"fragment".equals(name)) { 35640f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell return null; 35650f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 35660f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 35670f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell String fname = attrs.getAttributeValue(null, "class"); 35680f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell TypedArray a = context.obtainStyledAttributes(attrs, FragmentTag.Fragment); 35690f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (fname == null) { 35700f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fname = a.getString(FragmentTag.Fragment_name); 35710f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 35720f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell int id = a.getResourceId(FragmentTag.Fragment_id, View.NO_ID); 35730f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell String tag = a.getString(FragmentTag.Fragment_tag); 35740f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell a.recycle(); 35750f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 3576d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy if (!Fragment.isSupportFragmentClass(mHost.getContext(), fname)) { 35770f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // Invalid support lib fragment; let the device's framework handle it. 35780f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // This will allow android.app.Fragments to do the right thing. 35790f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell return null; 35800f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 35810f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 35820f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell int containerId = parent != null ? parent.getId() : 0; 35830f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (containerId == View.NO_ID && id == View.NO_ID && tag == null) { 35840f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell throw new IllegalArgumentException(attrs.getPositionDescription() 35850f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell + ": Must specify unique android:id, android:tag, or have a parent with an id for " + fname); 35860f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 35870f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 35880f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // If we restored from a previous state, we may already have 35890f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // instantiated this fragment from the state and should use 35900f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // that instance instead of making a new one. 35910f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell Fragment fragment = id != View.NO_ID ? findFragmentById(id) : null; 35920f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (fragment == null && tag != null) { 35930f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment = findFragmentByTag(tag); 35940f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 35950f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (fragment == null && containerId != View.NO_ID) { 35960f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment = findFragmentById(containerId); 35970f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 35980f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 35990f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (FragmentManagerImpl.DEBUG) Log.v(TAG, "onCreateView: id=0x" 36000f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell + Integer.toHexString(id) + " fname=" + fname 36010f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell + " existing=" + fragment); 36020f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (fragment == null) { 36034aebb5be19bbf9314e7474dd62df8dd915313436Adam Powell fragment = mContainer.instantiate(context, fname, null); 36040f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mFromLayout = true; 36050f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mFragmentId = id != 0 ? id : containerId; 36060f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mContainerId = containerId; 36070f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mTag = tag; 36080f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mInLayout = true; 36090f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mFragmentManager = this; 36101b84066e4233b4b0c8a32fffc30f95b8cd20ced4Chris Banes fragment.mHost = mHost; 3611b979cb86fa389effb7cd79fa045550c10b7b4819Todd Kennedy fragment.onInflate(mHost.getContext(), attrs, fragment.mSavedFragmentState); 36120f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell addFragment(fragment, true); 36130f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 36140f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } else if (fragment.mInLayout) { 36150f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // A fragment already exists and it is not one we restored from 36160f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // previous state. 36170f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell throw new IllegalArgumentException(attrs.getPositionDescription() 36180f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell + ": Duplicate id 0x" + Integer.toHexString(id) 36190f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell + ", tag " + tag + ", or parent id 0x" + Integer.toHexString(containerId) 36200f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell + " with another fragment for " + fname); 36210f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } else { 36220f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // This fragment was retained from a previous instance; get it 36230f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // going now. 36240f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mInLayout = true; 3625e4148d65bbd62585c68c5782c2081bab6b303568Todd Kennedy fragment.mHost = mHost; 36260f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // If this fragment is newly instantiated (either right now, or 36270f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // from last saved state), then give it the attributes to 36280f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // initialize itself. 36290f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (!fragment.mRetaining) { 3630b979cb86fa389effb7cd79fa045550c10b7b4819Todd Kennedy fragment.onInflate(mHost.getContext(), attrs, fragment.mSavedFragmentState); 36310f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 36320f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 36330f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 36340f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // If we haven't finished entering the CREATED state ourselves yet, 363537149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell // push the inflated child fragment along. This will ensureInflatedFragmentView 363637149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell // at the right phase of the lifecycle so that we will have mView populated 363737149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell // for compliant fragments below. 36380f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (mCurState < Fragment.CREATED && fragment.mFromLayout) { 36390f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell moveToState(fragment, Fragment.CREATED, 0, 0, false); 36400f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } else { 36410f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell moveToState(fragment); 36420f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 36430f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 36440f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (fragment.mView == null) { 36450f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell throw new IllegalStateException("Fragment " + fname 36460f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell + " did not create a view."); 36470f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 36480f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (id != 0) { 36490f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mView.setId(id); 36500f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 36510f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (fragment.mView.getTag() == null) { 36520f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mView.setTag(tag); 36530f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 36540f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell return fragment.mView; 36550f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 36560f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 36574bf8c3d1aeb944a993c946db770604b55f981341Aurimas Liutikas @Override 36584bf8c3d1aeb944a993c946db770604b55f981341Aurimas Liutikas public View onCreateView(String name, Context context, AttributeSet attrs) { 36594bf8c3d1aeb944a993c946db770604b55f981341Aurimas Liutikas return onCreateView(null, name, context, attrs); 36604bf8c3d1aeb944a993c946db770604b55f981341Aurimas Liutikas } 36614bf8c3d1aeb944a993c946db770604b55f981341Aurimas Liutikas 36624bf8c3d1aeb944a993c946db770604b55f981341Aurimas Liutikas LayoutInflater.Factory2 getLayoutInflaterFactory() { 36630f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell return this; 36640f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 36650f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 36660f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell static class FragmentTag { 36670f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell public static final int[] Fragment = { 36680f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 0x01010003, 0x010100d0, 0x010100d1 36690f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell }; 36700f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell public static final int Fragment_id = 1; 36710f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell public static final int Fragment_name = 0; 36720f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell public static final int Fragment_tag = 2; 36730f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 3674990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3675990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 3676990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * An add or pop transaction to be scheduled for the UI thread. 3677990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 3678990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount interface OpGenerator { 3679990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 3680990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Generate transactions to add to {@code records} and whether or not the transaction is 3681990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * an add or pop to {@code isRecordPop}. 3682990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 3683990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * records and isRecordPop must be added equally so that each transaction in records 3684990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * matches the boolean for whether or not it is a pop in isRecordPop. 3685990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 3686990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param records A list to add transactions to. 3687990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param isRecordPop A list to add whether or not the transactions added to records is 3688990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * a pop transaction. 3689990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @return true if something was added or false otherwise. 3690990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 3691990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean generateOps(ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop); 3692990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3693990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3694990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 3695990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * A pop operation OpGenerator. This will be run on the UI thread and will generate the 3696990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * transactions that will be popped if anything can be popped. 3697990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 3698990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private class PopBackStackState implements OpGenerator { 3699990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final String mName; 3700990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int mId; 3701990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int mFlags; 3702990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3703990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount PopBackStackState(String name, int id, int flags) { 3704990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mName = name; 3705990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mId = id; 3706990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mFlags = flags; 3707990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3708990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3709990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Override 3710990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public boolean generateOps(ArrayList<BackStackRecord> records, 3711990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Boolean> isRecordPop) { 3712418738949305a8a0e30eba92c125c650048f9c50Adam Powell if (mPrimaryNav != null // We have a primary nav fragment 3713418738949305a8a0e30eba92c125c650048f9c50Adam Powell && mId < 0 // No valid id (since they're local) 3714418738949305a8a0e30eba92c125c650048f9c50Adam Powell && mName == null) { // no name to pop to (since they're local) 3715418738949305a8a0e30eba92c125c650048f9c50Adam Powell final FragmentManager childManager = mPrimaryNav.peekChildFragmentManager(); 3716418738949305a8a0e30eba92c125c650048f9c50Adam Powell if (childManager != null && childManager.popBackStackImmediate()) { 3717418738949305a8a0e30eba92c125c650048f9c50Adam Powell // We didn't add any operations for this FragmentManager even though 3718418738949305a8a0e30eba92c125c650048f9c50Adam Powell // a child did do work. 3719418738949305a8a0e30eba92c125c650048f9c50Adam Powell return false; 3720418738949305a8a0e30eba92c125c650048f9c50Adam Powell } 3721418738949305a8a0e30eba92c125c650048f9c50Adam Powell } 3722990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return popBackStackState(records, isRecordPop, mName, mId, mFlags); 3723990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3724990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3725990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3726990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 3727990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * A listener for a postponed transaction. This waits until 3728990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@link Fragment#startPostponedEnterTransition()} is called or a transaction is started 3729990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * that interacts with this one, based on interactions with the fragment container. 3730990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 3731990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount static class StartEnterTransitionListener 3732990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount implements Fragment.OnStartEnterTransitionListener { 3733990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private final boolean mIsBack; 3734990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private final BackStackRecord mRecord; 3735990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private int mNumPostponed; 3736990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3737990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount StartEnterTransitionListener(BackStackRecord record, boolean isBack) { 3738990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mIsBack = isBack; 3739990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mRecord = record; 3740990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3741990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3742990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 3743990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Called from {@link Fragment#startPostponedEnterTransition()}, this decreases the 3744990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * number of Fragments that are postponed. This may cause the transaction to schedule 3745990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * to finish running and run transitions and animations. 3746990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 3747990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Override 3748990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void onStartEnterTransition() { 3749990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mNumPostponed--; 3750990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mNumPostponed != 0) { 3751990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return; 3752990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3753990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mRecord.mManager.scheduleCommit(); 3754990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3755990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3756990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 3757990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Called from {@link Fragment# 3758990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * setOnStartEnterTransitionListener(Fragment.OnStartEnterTransitionListener)}, this 3759990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * increases the number of fragments that are postponed as part of this transaction. 3760990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 3761990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Override 3762990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void startListening() { 3763990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mNumPostponed++; 3764990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3765990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3766990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 3767990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @return true if there are no more postponed fragments as part of the transaction. 3768990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 3769990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public boolean isReady() { 3770990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return mNumPostponed == 0; 3771990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3772990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3773990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 3774990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Completes the transaction and start the animations and transitions. This may skip 3775990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * the transitions if this is called before all fragments have called 3776990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@link Fragment#startPostponedEnterTransition()}. 3777990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 3778990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void completeTransaction() { 3779990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final boolean canceled; 3780990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount canceled = mNumPostponed > 0; 3781990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentManagerImpl manager = mRecord.mManager; 3782990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int numAdded = manager.mAdded.size(); 3783990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numAdded; i++) { 3784990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final Fragment fragment = manager.mAdded.get(i); 3785990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.setOnStartEnterTransitionListener(null); 3786990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (canceled && fragment.isPostponed()) { 3787990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.startPostponedEnterTransition(); 3788990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3789990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3790990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mRecord.mManager.completeExecute(mRecord, mIsBack, !canceled, true); 3791990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3792990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3793990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 3794990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Cancels this transaction instead of completing it. That means that the state isn't 3795990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * changed, so the pop results in no change to the state. 3796990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 3797990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void cancelTransaction() { 3798990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mRecord.mManager.completeExecute(mRecord, mIsBack, false, false); 3799990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3800990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3801cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn} 3802