FragmentManager.java revision 805fb8e2508edfc45a1b80a3bf63501aa3507bf2
1cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn/* 2ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * Copyright 2018 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 17ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.fragment.app; 18cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 19ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP; 2077f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount 2115e593ea3575512d7072240d1db9d74fad8749a3George Mountimport android.animation.Animator; 2215e593ea3575512d7072240d1db9d74fad8749a3George Mountimport android.animation.AnimatorInflater; 2315e593ea3575512d7072240d1db9d74fad8749a3George Mountimport android.animation.AnimatorListenerAdapter; 2415e593ea3575512d7072240d1db9d74fad8749a3George Mountimport android.animation.AnimatorSet; 2515e593ea3575512d7072240d1db9d74fad8749a3George Mountimport android.animation.PropertyValuesHolder; 2615e593ea3575512d7072240d1db9d74fad8749a3George Mountimport android.animation.ValueAnimator; 279277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackbornimport android.content.Context; 28cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.content.res.Configuration; 2936bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powellimport android.content.res.Resources.NotFoundException; 300f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powellimport android.content.res.TypedArray; 315e63ab9505a3a4d11374cbbec418c1aba921409dChris Banesimport android.os.Build; 32cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.os.Bundle; 33cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.os.Looper; 34cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.os.Parcel; 35cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.os.Parcelable; 360f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powellimport android.util.AttributeSet; 37cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.util.Log; 38cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.util.SparseArray; 39267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powellimport android.view.LayoutInflater; 40990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.view.Menu; 41990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.view.MenuInflater; 42990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.view.MenuItem; 43990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.view.View; 44990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.view.ViewGroup; 459277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackbornimport android.view.animation.AccelerateInterpolator; 469277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackbornimport android.view.animation.AlphaAnimation; 47cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.view.animation.Animation; 48990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.view.animation.Animation.AnimationListener; 499277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackbornimport android.view.animation.AnimationSet; 50cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.view.animation.AnimationUtils; 519277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackbornimport android.view.animation.DecelerateInterpolator; 529277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackbornimport android.view.animation.Interpolator; 539277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackbornimport android.view.animation.ScaleAnimation; 54e62545fdf58881a2d0426285648f71ce9323ca15George Mountimport android.view.animation.Transformation; 55cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 56320113721c2e14bbc2403809046fa2959a665c11Aurimas Liutikasimport androidx.annotation.CallSuper; 57320113721c2e14bbc2403809046fa2959a665c11Aurimas Liutikasimport androidx.annotation.IdRes; 58320113721c2e14bbc2403809046fa2959a665c11Aurimas Liutikasimport androidx.annotation.NonNull; 59380e247f873d0adf2be42bd9eb41d02322094f11Jake Whartonimport androidx.annotation.Nullable; 60320113721c2e14bbc2403809046fa2959a665c11Aurimas Liutikasimport androidx.annotation.RestrictTo; 61320113721c2e14bbc2403809046fa2959a665c11Aurimas Liutikasimport androidx.annotation.StringRes; 62320113721c2e14bbc2403809046fa2959a665c11Aurimas Liutikasimport androidx.collection.ArraySet; 63320113721c2e14bbc2403809046fa2959a665c11Aurimas Liutikasimport androidx.core.util.DebugUtils; 64320113721c2e14bbc2403809046fa2959a665c11Aurimas Liutikasimport androidx.core.util.LogWriter; 65320113721c2e14bbc2403809046fa2959a665c11Aurimas Liutikasimport androidx.core.view.ViewCompat; 66ba069d50913c3fb250bb60ec310439db36895337Alan Viveretteimport androidx.lifecycle.ViewModelStore; 67320113721c2e14bbc2403809046fa2959a665c11Aurimas Liutikas 68cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport java.io.FileDescriptor; 69cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport java.io.PrintWriter; 70d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liuimport java.lang.reflect.Field; 71cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport java.util.ArrayList; 72cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport java.util.Arrays; 7396221034e4a23a2abb83f772a0281bb197ac5ac0George Mountimport java.util.Collections; 743a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brownimport java.util.List; 75267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powellimport java.util.concurrent.CopyOnWriteArrayList; 76267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 77cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn/** 78cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Static library support version of the framework's {@link android.app.FragmentManager}. 79cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Used to write apps that run on platforms prior to Android 3.0. When running 80cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * on Android 3.0 or above, this implementation is still used; it does not try 819dcd2e58138ca4eb4b18f80b50e8979329e859d6Scott Main * to switch to the framework's implementation. See the framework {@link FragmentManager} 82cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * documentation for a class overview. 839dcd2e58138ca4eb4b18f80b50e8979329e859d6Scott Main * 849dcd2e58138ca4eb4b18f80b50e8979329e859d6Scott Main * <p>Your activity must derive from {@link FragmentActivity} to use this. From such an activity, 859dcd2e58138ca4eb4b18f80b50e8979329e859d6Scott Main * you can acquire the {@link FragmentManager} by calling 869dcd2e58138ca4eb4b18f80b50e8979329e859d6Scott Main * {@link FragmentActivity#getSupportFragmentManager}. 87cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 88cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornpublic abstract class FragmentManager { 89cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 90cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Representation of an entry on the fragment back stack, as created 91cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * with {@link FragmentTransaction#addToBackStack(String) 92cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * FragmentTransaction.addToBackStack()}. Entries can later be 93cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * retrieved with {@link FragmentManager#getBackStackEntryAt(int) 94fd28b81e0501d11989a8ad095c1a54619000df19Aurimas Liutikas * FragmentManager.getBackStackEntryAt()}. 95cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * 96cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * <p>Note that you should never hold on to a BackStackEntry object; 97cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * the identifier as returned by {@link #getId} is the only thing that 98cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * will be persisted across activity instances. 99cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 100cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public interface BackStackEntry { 101cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 102cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Return the unique identifier for the entry. This is the only 103cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * representation of the entry that will persist across activity 104cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * instances. 105cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 106cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public int getId(); 107cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 108cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 1092a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn * Get the name that was supplied to 1102a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn * {@link FragmentTransaction#addToBackStack(String) 1112a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn * FragmentTransaction.addToBackStack(String)} when creating this entry. 1122a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn */ 113380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @Nullable 1142a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn public String getName(); 1152a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn 1162a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn /** 117cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Return the full bread crumb title resource identifier for the entry, 118cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * or 0 if it does not have one. 119cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 120a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye @StringRes 121cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public int getBreadCrumbTitleRes(); 122cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 123cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 124cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Return the short bread crumb title resource identifier for the entry, 125cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * or 0 if it does not have one. 126cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 127a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye @StringRes 128cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public int getBreadCrumbShortTitleRes(); 129cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 130cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 131cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Return the full bread crumb title for the entry, or null if it 132cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * does not have one. 133cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 134380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @Nullable 135cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public CharSequence getBreadCrumbTitle(); 136cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 137cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 138cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Return the short bread crumb title for the entry, or null if it 139cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * does not have one. 140cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 141380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @Nullable 142cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public CharSequence getBreadCrumbShortTitle(); 143cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 144cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 145cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 146cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Interface to watch for changes to the back stack. 147cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 148cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public interface OnBackStackChangedListener { 149cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 150cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Called whenever the contents of the back stack change. 151cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 152cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void onBackStackChanged(); 153cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 154cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 155cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 156cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Start a series of edit operations on the Fragments associated with 157cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * this FragmentManager. 158dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas * 159cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * <p>Note: A fragment transaction can only be created/committed prior 160cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * to an activity saving its state. If you try to commit a transaction 161cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * after {@link FragmentActivity#onSaveInstanceState FragmentActivity.onSaveInstanceState()} 162cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * (and prior to a following {@link FragmentActivity#onStart FragmentActivity.onStart} 163cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * or {@link FragmentActivity#onResume FragmentActivity.onResume()}, you will get an error. 164cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * This is because the framework takes care of saving your current fragments 165cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * in the state, and if changes are made after the state is saved then they 166cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * will be lost.</p> 167cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 168380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @NonNull 169cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract FragmentTransaction beginTransaction(); 170cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 171d805095048f6be52cddbd572ee343c4639ba8187Alan Viverette /** 172d805095048f6be52cddbd572ee343c4639ba8187Alan Viverette * @hide -- remove once prebuilts are in. 173d805095048f6be52cddbd572ee343c4639ba8187Alan Viverette * @deprecated 174d805095048f6be52cddbd572ee343c4639ba8187Alan Viverette */ 1758e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas @RestrictTo(LIBRARY_GROUP) 176cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Deprecated 177cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public FragmentTransaction openTransaction() { 178cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return beginTransaction(); 179cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 180dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 181cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 182cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * After a {@link FragmentTransaction} is committed with 183cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * {@link FragmentTransaction#commit FragmentTransaction.commit()}, it 184cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * is scheduled to be executed asynchronously on the process's main thread. 185cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * If you want to immediately executing any such pending operations, you 186cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * can call this function (only from the main thread) to do so. Note that 187cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * all callbacks and other related behavior will be done from within this 188cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * call, so be careful about where this is called from. 189cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * 1901500716b2257e9f442606fe5bd992ab4e0198dcbAdam Powell * <p>If you are committing a single transaction that does not modify the 1911500716b2257e9f442606fe5bd992ab4e0198dcbAdam Powell * fragment back stack, strongly consider using 1921500716b2257e9f442606fe5bd992ab4e0198dcbAdam Powell * {@link FragmentTransaction#commitNow()} instead. This can help avoid 1931500716b2257e9f442606fe5bd992ab4e0198dcbAdam Powell * unwanted side effects when other code in your app has pending committed 1941500716b2257e9f442606fe5bd992ab4e0198dcbAdam Powell * transactions that expect different timing.</p> 195990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * <p> 196990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * This also forces the start of any postponed Transactions where 197990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@link Fragment#postponeEnterTransition()} has been called. 1981500716b2257e9f442606fe5bd992ab4e0198dcbAdam Powell * 199cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @return Returns true if there were any pending transactions to be 200cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * executed. 201cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 202cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract boolean executePendingTransactions(); 203cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 204cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 205cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Finds a fragment that was identified by the given id either when inflated 206cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * from XML or as the container ID when added in a transaction. This first 207cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * searches through fragments that are currently added to the manager's 208cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * activity; if no such fragment is found, then all fragments currently 209cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * on the back stack associated with this ID are searched. 210cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @return The fragment if found or null otherwise. 211cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 212380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @Nullable 213a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye public abstract Fragment findFragmentById(@IdRes int id); 214cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 215cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 216cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Finds a fragment that was identified by the given tag either when inflated 217cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * from XML or as supplied when added in a transaction. This first 218cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * searches through fragments that are currently added to the manager's 219cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * activity; if no such fragment is found, then all fragments currently 220cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * on the back stack are searched. 221cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @return The fragment if found or null otherwise. 222cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 223380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @Nullable 224380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton public abstract Fragment findFragmentByTag(@Nullable String tag); 225cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 226cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 227cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Flag for {@link #popBackStack(String, int)} 228cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * and {@link #popBackStack(int, int)}: If set, and the name or ID of 229cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * a back stack entry has been supplied, then all matching entries will 230cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * be consumed until one that doesn't match is found or the bottom of 231cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * the stack is reached. Otherwise, all entries up to but not including that entry 232cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * will be removed. 233cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 234cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public static final int POP_BACK_STACK_INCLUSIVE = 1<<0; 235cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 236cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 237cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Pop the top state off the back stack. Returns true if there was one 238cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * to pop, else false. This function is asynchronous -- it enqueues the 239cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * request to pop, but the action will not be performed until the application 240cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * returns to its event loop. 241cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 242cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract void popBackStack(); 243cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 244cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 245cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Like {@link #popBackStack()}, but performs the operation immediately 246cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * inside of the call. This is like calling {@link #executePendingTransactions()} 247990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * afterwards without forcing the start of postponed Transactions. 248cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @return Returns true if there was something popped, else false. 249cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 250cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract boolean popBackStackImmediate(); 251cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 252cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 253cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Pop the last fragment transition from the manager's fragment 254cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * back stack. If there is nothing to pop, false is returned. 255cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * This function is asynchronous -- it enqueues the 256cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * request to pop, but the action will not be performed until the application 257cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * returns to its event loop. 258dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas * 259cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param name If non-null, this is the name of a previous back state 260cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * to look for; if found, all states up to that state will be popped. The 261cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * {@link #POP_BACK_STACK_INCLUSIVE} flag can be used to control whether 262cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * the named state itself is popped. If null, only the top state is popped. 263cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param flags Either 0 or {@link #POP_BACK_STACK_INCLUSIVE}. 264cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 265380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton public abstract void popBackStack(@Nullable String name, int flags); 266cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 267cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 268cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Like {@link #popBackStack(String, int)}, but performs the operation immediately 269cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * inside of the call. This is like calling {@link #executePendingTransactions()} 270990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * afterwards without forcing the start of postponed Transactions. 271cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @return Returns true if there was something popped, else false. 272cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 273380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton public abstract boolean popBackStackImmediate(@Nullable String name, int flags); 274cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 275cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 276cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Pop all back stack states up to the one with the given identifier. 277cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * This function is asynchronous -- it enqueues the 278cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * request to pop, but the action will not be performed until the application 279cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * returns to its event loop. 280dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas * 281cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param id Identifier of the stated to be popped. If no identifier exists, 282cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * false is returned. 283cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * The identifier is the number returned by 284cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * {@link FragmentTransaction#commit() FragmentTransaction.commit()}. The 285cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * {@link #POP_BACK_STACK_INCLUSIVE} flag can be used to control whether 286cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * the named state itself is popped. 287cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param flags Either 0 or {@link #POP_BACK_STACK_INCLUSIVE}. 288cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 289cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract void popBackStack(int id, int flags); 290cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 291cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 292cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Like {@link #popBackStack(int, int)}, but performs the operation immediately 293cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * inside of the call. This is like calling {@link #executePendingTransactions()} 294990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * afterwards without forcing the start of postponed Transactions. 295cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @return Returns true if there was something popped, else false. 296cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 297cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract boolean popBackStackImmediate(int id, int flags); 298cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 299cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 300cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Return the number of entries currently in the back stack. 301cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 302cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract int getBackStackEntryCount(); 303cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 304cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 305cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Return the BackStackEntry at index <var>index</var> in the back stack; 306cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * entries start index 0 being the bottom of the stack. 307cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 308380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @NonNull 309cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract BackStackEntry getBackStackEntryAt(int index); 310cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 311cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 312cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Add a new listener for changes to the fragment back stack. 313cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 314380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton public abstract void addOnBackStackChangedListener( 315380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @NonNull OnBackStackChangedListener listener); 316cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 317cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 318cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Remove a listener that was previously added with 319cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * {@link #addOnBackStackChangedListener(OnBackStackChangedListener)}. 320cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 321380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton public abstract void removeOnBackStackChangedListener( 322380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @NonNull OnBackStackChangedListener listener); 323cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 324cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 325cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Put a reference to a fragment in a Bundle. This Bundle can be 326cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * persisted as saved state, and when later restoring 327cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * {@link #getFragment(Bundle, String)} will return the current 328cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * instance of the same fragment. 329cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * 330cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param bundle The bundle in which to put the fragment reference. 331cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param key The name of the entry in the bundle. 332cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param fragment The Fragment whose reference is to be stored. 333cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 334380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton public abstract void putFragment(@NonNull Bundle bundle, @NonNull String key, 335380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @NonNull Fragment fragment); 336cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 337cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 338cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Retrieve the current Fragment instance for a reference previously 339cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * placed with {@link #putFragment(Bundle, String, Fragment)}. 340cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * 341cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param bundle The bundle from which to retrieve the fragment reference. 342cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param key The name of the entry in the bundle. 343cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @return Returns the current Fragment instance that is associated with 344cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * the given reference. 345cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 346380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @Nullable 347380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton public abstract Fragment getFragment(@NonNull Bundle bundle, @NonNull String key); 348cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 349cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 3501af440bacb04c42ca18ad58cbcefa01b41c6792eGeorge Mount * Get a list of all fragments that are currently added to the FragmentManager. 35196221034e4a23a2abb83f772a0281bb197ac5ac0George Mount * This may include those that are hidden as well as those that are shown. 35296221034e4a23a2abb83f772a0281bb197ac5ac0George Mount * This will not include any fragments only in the back stack, or fragments that 35396221034e4a23a2abb83f772a0281bb197ac5ac0George Mount * are detached or removed. 3541af440bacb04c42ca18ad58cbcefa01b41c6792eGeorge Mount * <p> 3551af440bacb04c42ca18ad58cbcefa01b41c6792eGeorge Mount * The order of the fragments in the list is the order in which they were 3561af440bacb04c42ca18ad58cbcefa01b41c6792eGeorge Mount * added or attached. 3573a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown * 3581af440bacb04c42ca18ad58cbcefa01b41c6792eGeorge Mount * @return A list of all fragments that are added to the FragmentManager. 3593a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown */ 360380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @NonNull 3611af440bacb04c42ca18ad58cbcefa01b41c6792eGeorge Mount public abstract List<Fragment> getFragments(); 3623a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown 3633a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown /** 3645c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * Save the current instance state of the given Fragment. This can be 3655c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * used later when creating a new instance of the Fragment and adding 3665c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * it to the fragment manager, to have it create itself to match the 3675c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * current state returned here. Note that there are limits on how 3685c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * this can be used: 3695c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * 3705c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * <ul> 3715c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * <li>The Fragment must currently be attached to the FragmentManager. 3725c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * <li>A new Fragment created using this saved state must be the same class 3735c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * type as the Fragment it was created from. 3745c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * <li>The saved state can not contain dependencies on other fragments -- 3755c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * that is it can't use {@link #putFragment(Bundle, String, Fragment)} to 3765c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * store a fragment reference because that reference may not be valid when 3775c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * this saved state is later used. Likewise the Fragment's target and 3785c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * result code are not included in this state. 3795c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * </ul> 3805c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * 3815c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * @param f The Fragment whose state is to be saved. 3825c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * @return The generated state. This will be null if there was no 3835c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn * interesting state created by the fragment. 3845c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn */ 385380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @Nullable 3865c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn public abstract Fragment.SavedState saveFragmentInstanceState(Fragment f); 3875c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn 3885c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn /** 38901df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler * Returns true if the final {@link android.app.Activity#onDestroy() Activity.onDestroy()} 39001df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler * call has been made on the FragmentManager's Activity, so this instance is now dead. 39101df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler */ 39201df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler public abstract boolean isDestroyed(); 39301df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler 39401df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler /** 395267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Registers a {@link FragmentLifecycleCallbacks} to listen to fragment lifecycle events 396267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * happening in this FragmentManager. All registered callbacks will be automatically 397267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * unregistered when this FragmentManager is destroyed. 398267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 399267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param cb Callbacks to register 400267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param recursive true to automatically register this callback for all child FragmentManagers 401267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 402380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton public abstract void registerFragmentLifecycleCallbacks(@NonNull FragmentLifecycleCallbacks cb, 403267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell boolean recursive); 404267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 405267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 406267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Unregisters a previously registered {@link FragmentLifecycleCallbacks}. If the callback 407267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * was not previously registered this call has no effect. All registered callbacks will be 408267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * automatically unregistered when this FragmentManager is destroyed. 409267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 410267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param cb Callbacks to unregister 411267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 412380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton public abstract void unregisterFragmentLifecycleCallbacks( 413380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @NonNull FragmentLifecycleCallbacks cb); 414267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 415267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 416418738949305a8a0e30eba92c125c650048f9c50Adam Powell * Return the currently active primary navigation fragment for this FragmentManager. 4171d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell * The primary navigation fragment is set by fragment transactions using 4181d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell * {@link FragmentTransaction#setPrimaryNavigationFragment(Fragment)}. 419418738949305a8a0e30eba92c125c650048f9c50Adam Powell * 420418738949305a8a0e30eba92c125c650048f9c50Adam Powell * <p>The primary navigation fragment's 421418738949305a8a0e30eba92c125c650048f9c50Adam Powell * {@link Fragment#getChildFragmentManager() child FragmentManager} will be called first 422418738949305a8a0e30eba92c125c650048f9c50Adam Powell * to process delegated navigation actions such as {@link #popBackStack()} if no ID 423418738949305a8a0e30eba92c125c650048f9c50Adam Powell * or transaction name is provided to pop to.</p> 424418738949305a8a0e30eba92c125c650048f9c50Adam Powell * 425418738949305a8a0e30eba92c125c650048f9c50Adam Powell * @return the fragment designated as the primary navigation fragment 426418738949305a8a0e30eba92c125c650048f9c50Adam Powell */ 427380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @Nullable 428418738949305a8a0e30eba92c125c650048f9c50Adam Powell public abstract Fragment getPrimaryNavigationFragment(); 429418738949305a8a0e30eba92c125c650048f9c50Adam Powell 430418738949305a8a0e30eba92c125c650048f9c50Adam Powell /** 431cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Print the FragmentManager's state into the given stream. 432cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * 433cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param prefix Text to print at the front of each line. 434cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param fd The raw file descriptor that the dump is being sent to. 435cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param writer A PrintWriter to which the dump is to be set. 436cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @param args Additional arguments to the dump request. 437cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 438cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public abstract void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args); 439cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 440cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 441cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Control whether the framework's internal fragment manager debugging 442cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * logs are turned on. If enabled, you will see output in logcat as 443cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * the framework performs fragment operations. 444cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 445cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public static void enableDebugLogging(boolean enabled) { 446cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentManagerImpl.DEBUG = enabled; 447cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 448267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 449267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 45047844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount * Returns {@code true} if the FragmentManager's state has already been saved 45147844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount * by its host. Any operations that would change saved state should not be performed 45247844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount * if this method returns true. For example, any popBackStack() method, such as 45347844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount * {@link #popBackStackImmediate()} or any FragmentTransaction using 45447844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount * {@link FragmentTransaction#commit()} instead of 45547844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount * {@link FragmentTransaction#commitAllowingStateLoss()} will change 45647844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount * the state and will result in an error. 45747844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount * 45847844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount * @return true if this FragmentManager's state has already been saved by its host 45947844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount */ 46047844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount public abstract boolean isStateSaved(); 46147844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount 46247844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount /** 463267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Callback interface for listening to fragment state changes that happen 464267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * within a given FragmentManager. 465267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 4661b5b6c012765919f50bfb64dcf494a2d8cfcfbb1Adam Powell public abstract static class FragmentLifecycleCallbacks { 467267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 468267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Called right before the fragment's {@link Fragment#onAttach(Context)} method is called. 4691d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell * This is a good time to inject any required dependencies or perform other configuration 4701d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell * for the fragment before any of the fragment's lifecycle methods are invoked. 471267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 472267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param fm Host FragmentManager 473267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param f Fragment changing state 474267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param context Context that the Fragment is being attached to 475267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 476380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton public void onFragmentPreAttached(@NonNull FragmentManager fm, @NonNull Fragment f, 477380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @NonNull Context context) {} 478267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 479267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 480267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Called after the fragment has been attached to its host. Its host will have had 481267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * <code>onAttachFragment</code> called before this call happens. 482267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 483267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param fm Host FragmentManager 484267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param f Fragment changing state 485267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param context Context that the Fragment was attached to 486267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 487380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton public void onFragmentAttached(@NonNull FragmentManager fm, @NonNull Fragment f, 488380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @NonNull Context context) {} 489267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 490267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 4911d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell * Called right before the fragment's {@link Fragment#onCreate(Bundle)} method is called. 4921d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell * This is a good time to inject any required dependencies or perform other configuration 4931d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell * for the fragment. 4941d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell * 4951d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell * @param fm Host FragmentManager 4961d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell * @param f Fragment changing state 4971d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell * @param savedInstanceState Saved instance bundle from a previous instance 4981d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell */ 499380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton public void onFragmentPreCreated(@NonNull FragmentManager fm, @NonNull Fragment f, 500380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @Nullable Bundle savedInstanceState) {} 5011d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell 5021d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell /** 503267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Called after the fragment has returned from the FragmentManager's call to 504267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * {@link Fragment#onCreate(Bundle)}. This will only happen once for any given 505267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * fragment instance, though the fragment may be attached and detached multiple times. 506267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 507267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param fm Host FragmentManager 508267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param f Fragment changing state 509267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param savedInstanceState Saved instance bundle from a previous instance 510267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 511380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton public void onFragmentCreated(@NonNull FragmentManager fm, @NonNull Fragment f, 512380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @Nullable Bundle savedInstanceState) {} 513267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 514267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 515267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Called after the fragment has returned from the FragmentManager's call to 516267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * {@link Fragment#onActivityCreated(Bundle)}. This will only happen once for any given 517267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * fragment instance, though the fragment may be attached and detached multiple times. 518267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 519267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param fm Host FragmentManager 520267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param f Fragment changing state 521267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param savedInstanceState Saved instance bundle from a previous instance 522267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 523380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton public void onFragmentActivityCreated(@NonNull FragmentManager fm, @NonNull Fragment f, 524380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @Nullable Bundle savedInstanceState) {} 525267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 526267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 527267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Called after the fragment has returned a non-null view from the FragmentManager's 528267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * request to {@link Fragment#onCreateView(LayoutInflater, ViewGroup, Bundle)}. 529267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 530267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param fm Host FragmentManager 531267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param f Fragment that created and owns the view 532267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param v View returned by the fragment 533267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param savedInstanceState Saved instance bundle from a previous instance 534267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 535380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton public void onFragmentViewCreated(@NonNull FragmentManager fm, @NonNull Fragment f, 536380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @NonNull View v, @Nullable Bundle savedInstanceState) {} 537267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 538267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 539267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Called after the fragment has returned from the FragmentManager's call to 540267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * {@link Fragment#onStart()}. 541267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 542267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param fm Host FragmentManager 543267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param f Fragment changing state 544267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 545380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton public void onFragmentStarted(@NonNull FragmentManager fm, @NonNull Fragment f) {} 546267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 547267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 548267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Called after the fragment has returned from the FragmentManager's call to 549267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * {@link Fragment#onResume()}. 550267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 551267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param fm Host FragmentManager 552267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param f Fragment changing state 553267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 554380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton public void onFragmentResumed(@NonNull FragmentManager fm, @NonNull Fragment f) {} 555267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 556267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 557267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Called after the fragment has returned from the FragmentManager's call to 558267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * {@link Fragment#onPause()}. 559267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 560267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param fm Host FragmentManager 561267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param f Fragment changing state 562267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 563380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton public void onFragmentPaused(@NonNull FragmentManager fm, @NonNull Fragment f) {} 564267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 565267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 566267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Called after the fragment has returned from the FragmentManager's call to 567267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * {@link Fragment#onStop()}. 568267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 569267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param fm Host FragmentManager 570267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param f Fragment changing state 571267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 572380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton public void onFragmentStopped(@NonNull FragmentManager fm, @NonNull Fragment f) {} 573267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 574267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 575267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Called after the fragment has returned from the FragmentManager's call to 576267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * {@link Fragment#onSaveInstanceState(Bundle)}. 577267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 578267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param fm Host FragmentManager 579267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param f Fragment changing state 580267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param outState Saved state bundle for the fragment 581267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 582380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton public void onFragmentSaveInstanceState(@NonNull FragmentManager fm, @NonNull Fragment f, 583380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @NonNull Bundle outState) {} 584267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 585267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 586267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Called after the fragment has returned from the FragmentManager's call to 587267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * {@link Fragment#onDestroyView()}. 588267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 589267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param fm Host FragmentManager 590267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param f Fragment changing state 591267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 592380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton public void onFragmentViewDestroyed(@NonNull FragmentManager fm, @NonNull Fragment f) {} 593267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 594267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 595267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Called after the fragment has returned from the FragmentManager's call to 596267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * {@link Fragment#onDestroy()}. 597267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 598267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param fm Host FragmentManager 599267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param f Fragment changing state 600267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 601380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton public void onFragmentDestroyed(@NonNull FragmentManager fm, @NonNull Fragment f) {} 602267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 603267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell /** 604267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * Called after the fragment has returned from the FragmentManager's call to 605267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * {@link Fragment#onDetach()}. 606267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * 607267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param fm Host FragmentManager 608267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell * @param f Fragment changing state 609267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell */ 610380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton public void onFragmentDetached(@NonNull FragmentManager fm, @NonNull Fragment f) {} 611267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 612cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn} 613cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 614cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornfinal class FragmentManagerState implements Parcelable { 615cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentState[] mActive; 616cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int[] mAdded; 617cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn BackStackState[] mBackStack; 618418738949305a8a0e30eba92c125c650048f9c50Adam Powell int mPrimaryNavActiveIndex = -1; 61990b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount int mNextFragmentIndex; 620dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 621cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public FragmentManagerState() { 622cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 623dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 624cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public FragmentManagerState(Parcel in) { 625cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mActive = in.createTypedArray(FragmentState.CREATOR); 626cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAdded = in.createIntArray(); 627cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStack = in.createTypedArray(BackStackState.CREATOR); 628418738949305a8a0e30eba92c125c650048f9c50Adam Powell mPrimaryNavActiveIndex = in.readInt(); 62990b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount mNextFragmentIndex = in.readInt(); 630cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 63190ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas 63290ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas @Override 633cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public int describeContents() { 634cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return 0; 635cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 636cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 63790ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas @Override 638cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void writeToParcel(Parcel dest, int flags) { 639cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn dest.writeTypedArray(mActive, flags); 640cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn dest.writeIntArray(mAdded); 641cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn dest.writeTypedArray(mBackStack, flags); 642418738949305a8a0e30eba92c125c650048f9c50Adam Powell dest.writeInt(mPrimaryNavActiveIndex); 64390b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount dest.writeInt(mNextFragmentIndex); 644cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 645dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 646cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public static final Parcelable.Creator<FragmentManagerState> CREATOR 647cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn = new Parcelable.Creator<FragmentManagerState>() { 64890ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas @Override 649cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public FragmentManagerState createFromParcel(Parcel in) { 650cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return new FragmentManagerState(in); 651cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 65290ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas 65390ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas @Override 654cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public FragmentManagerState[] newArray(int size) { 655cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return new FragmentManagerState[size]; 656cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 657cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn }; 658cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn} 659cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 660cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn/** 661cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Container for fragments associated with an activity. 662cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 6634bf8c3d1aeb944a993c946db770604b55f981341Aurimas Liutikasfinal class FragmentManagerImpl extends FragmentManager implements LayoutInflater.Factory2 { 664cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn static boolean DEBUG = false; 665cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn static final String TAG = "FragmentManager"; 666dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 667cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn static final String TARGET_REQUEST_CODE_STATE_TAG = "android:target_req_state"; 668cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn static final String TARGET_STATE_TAG = "android:target_state"; 669cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn static final String VIEW_STATE_TAG = "android:view_state"; 67079398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell static final String USER_VISIBLE_HINT_TAG = "android:user_visible_hint"; 671cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 672805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton private static final class FragmentLifecycleCallbacksHolder { 673805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton final FragmentLifecycleCallbacks mCallback; 674805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton final boolean mRecursive; 675805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton 676805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton FragmentLifecycleCallbacksHolder(FragmentLifecycleCallbacks callback, boolean recursive) { 677805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton mCallback = callback; 678805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton mRecursive = recursive; 679805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton } 680805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton } 681805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton 682990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<OpGenerator> mPendingActions; 683cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn boolean mExecutingActions; 684dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 68590b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount int mNextFragmentIndex = 0; 68690b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount 687ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount final ArrayList<Fragment> mAdded = new ArrayList<>(); 68890b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount SparseArray<Fragment> mActive; 689cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ArrayList<BackStackRecord> mBackStack; 690cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ArrayList<Fragment> mCreatedMenus; 691dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 692cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Must be accessed while locked. 693cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ArrayList<BackStackRecord> mBackStackIndices; 694cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ArrayList<Integer> mAvailBackStackIndices; 695cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 696cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ArrayList<OnBackStackChangedListener> mBackStackChangeListeners; 697805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton private final CopyOnWriteArrayList<FragmentLifecycleCallbacksHolder> 698189da768c7798462090ca9bc60f279f98e5d3ac5Aurimas Liutikas mLifecycleCallbacks = new CopyOnWriteArrayList<>(); 699cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 700cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int mCurState = Fragment.INITIALIZING; 7018491eb62f621cd5de4b4caed839be09c77011f53Todd Kennedy FragmentHostCallback mHost; 7020adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn FragmentContainer mContainer; 7030adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn Fragment mParent; 704380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @Nullable Fragment mPrimaryNav; 705d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu 706d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu static Field sAnimationListenerField = null; 707dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 708cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn boolean mNeedMenuInvalidate; 709cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn boolean mStateSaved; 7100d429d5f5bb0d6197d5c7a24b5c0bb5bcd5db8cdIan Lake boolean mStopped; 711cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn boolean mDestroyed; 712cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn String mNoTransactionsBecause; 71379398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell boolean mHavePendingDeferredStart; 714dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 715fda5be2466024a656152015c45a7681361d399bbGeorge Mount // Temporary vars for removing redundant operations in BackStackRecords: 716990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<BackStackRecord> mTmpRecords; 717990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Boolean> mTmpIsPop; 718990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Fragment> mTmpAddedFragments; 719990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 720cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Temporary vars for state save and restore. 721cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Bundle mStateBundle = null; 722cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn SparseArray<Parcelable> mStateArray = null; 723dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 724990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Postponed transactions. 725990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<StartEnterTransitionListener> mPostponedTransactions; 726990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 72725806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount // Saved FragmentManagerNonConfig during saveAllState() and cleared in noteStateNotSaved() 72825806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount FragmentManagerNonConfig mSavedNonConfig; 72925806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount 730cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Runnable mExecCommit = new Runnable() { 731cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 732cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void run() { 733cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn execPendingActions(); 734cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 735cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn }; 736cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 73715e593ea3575512d7072240d1db9d74fad8749a3George Mount static boolean modifiesAlpha(AnimationOrAnimator anim) { 73815e593ea3575512d7072240d1db9d74fad8749a3George Mount if (anim.animation instanceof AlphaAnimation) { 73903526560f132021f8fd7290259762ab362d4d567Doris Liu return true; 74015e593ea3575512d7072240d1db9d74fad8749a3George Mount } else if (anim.animation instanceof AnimationSet) { 74115e593ea3575512d7072240d1db9d74fad8749a3George Mount List<Animation> anims = ((AnimationSet) anim.animation).getAnimations(); 74203526560f132021f8fd7290259762ab362d4d567Doris Liu for (int i = 0; i < anims.size(); i++) { 74303526560f132021f8fd7290259762ab362d4d567Doris Liu if (anims.get(i) instanceof AlphaAnimation) { 74403526560f132021f8fd7290259762ab362d4d567Doris Liu return true; 74503526560f132021f8fd7290259762ab362d4d567Doris Liu } 74603526560f132021f8fd7290259762ab362d4d567Doris Liu } 74715e593ea3575512d7072240d1db9d74fad8749a3George Mount return false; 74815e593ea3575512d7072240d1db9d74fad8749a3George Mount } else { 74915e593ea3575512d7072240d1db9d74fad8749a3George Mount return modifiesAlpha(anim.animator); 75015e593ea3575512d7072240d1db9d74fad8749a3George Mount } 75115e593ea3575512d7072240d1db9d74fad8749a3George Mount } 75215e593ea3575512d7072240d1db9d74fad8749a3George Mount 75315e593ea3575512d7072240d1db9d74fad8749a3George Mount static boolean modifiesAlpha(Animator anim) { 75415e593ea3575512d7072240d1db9d74fad8749a3George Mount if (anim == null) { 75515e593ea3575512d7072240d1db9d74fad8749a3George Mount return false; 75615e593ea3575512d7072240d1db9d74fad8749a3George Mount } 75715e593ea3575512d7072240d1db9d74fad8749a3George Mount if (anim instanceof ValueAnimator) { 75815e593ea3575512d7072240d1db9d74fad8749a3George Mount ValueAnimator valueAnim = (ValueAnimator) anim; 75915e593ea3575512d7072240d1db9d74fad8749a3George Mount PropertyValuesHolder[] values = valueAnim.getValues(); 76015e593ea3575512d7072240d1db9d74fad8749a3George Mount for (int i = 0; i < values.length; i++) { 76115e593ea3575512d7072240d1db9d74fad8749a3George Mount if (("alpha").equals(values[i].getPropertyName())) { 76215e593ea3575512d7072240d1db9d74fad8749a3George Mount return true; 76315e593ea3575512d7072240d1db9d74fad8749a3George Mount } 76415e593ea3575512d7072240d1db9d74fad8749a3George Mount } 76515e593ea3575512d7072240d1db9d74fad8749a3George Mount } else if (anim instanceof AnimatorSet) { 76615e593ea3575512d7072240d1db9d74fad8749a3George Mount List<Animator> animList = ((AnimatorSet) anim).getChildAnimations(); 76715e593ea3575512d7072240d1db9d74fad8749a3George Mount for (int i = 0; i < animList.size(); i++) { 76815e593ea3575512d7072240d1db9d74fad8749a3George Mount if (modifiesAlpha(animList.get(i))) { 76915e593ea3575512d7072240d1db9d74fad8749a3George Mount return true; 77015e593ea3575512d7072240d1db9d74fad8749a3George Mount } 77115e593ea3575512d7072240d1db9d74fad8749a3George Mount } 77203526560f132021f8fd7290259762ab362d4d567Doris Liu } 77303526560f132021f8fd7290259762ab362d4d567Doris Liu return false; 77403526560f132021f8fd7290259762ab362d4d567Doris Liu } 77503526560f132021f8fd7290259762ab362d4d567Doris Liu 77615e593ea3575512d7072240d1db9d74fad8749a3George Mount static boolean shouldRunOnHWLayer(View v, AnimationOrAnimator anim) { 77715e593ea3575512d7072240d1db9d74fad8749a3George Mount if (v == null || anim == null) { 77815e593ea3575512d7072240d1db9d74fad8749a3George Mount return false; 77915e593ea3575512d7072240d1db9d74fad8749a3George Mount } 780b8d65fef161c7cd4bb06dc97685cf3fb3d6c3e1aChris Banes return Build.VERSION.SDK_INT >= 19 781fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas && v.getLayerType() == View.LAYER_TYPE_NONE 78203526560f132021f8fd7290259762ab362d4d567Doris Liu && ViewCompat.hasOverlappingRendering(v) 78303526560f132021f8fd7290259762ab362d4d567Doris Liu && modifiesAlpha(anim); 78403526560f132021f8fd7290259762ab362d4d567Doris Liu } 78503526560f132021f8fd7290259762ab362d4d567Doris Liu 78613fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn private void throwException(RuntimeException ex) { 78713fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn Log.e(TAG, ex.getMessage()); 788ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn Log.e(TAG, "Activity state:"); 78913fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn LogWriter logw = new LogWriter(TAG); 79013fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn PrintWriter pw = new PrintWriter(logw); 791d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy if (mHost != null) { 792ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn try { 7938491eb62f621cd5de4b4caed839be09c77011f53Todd Kennedy mHost.onDump(" ", null, pw, new String[] { }); 794ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn } catch (Exception e) { 795ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn Log.e(TAG, "Failed dumping state", e); 796ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn } 797ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn } else { 798ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn try { 79913fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn dump(" ", null, pw, new String[] { }); 800ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn } catch (Exception e) { 80113fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn Log.e(TAG, "Failed dumping state", e); 802ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn } 803ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn } 80413fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn throw ex; 805ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn } 806ec9fb2522d42d1ff73ddffa12b318d925c10ab18Dianne Hackborn 807cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 808cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public FragmentTransaction beginTransaction() { 809cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return new BackStackRecord(this); 810cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 811cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 812cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 813cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean executePendingTransactions() { 814990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean updates = execPendingActions(); 815990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount forcePostponedTransactions(); 816990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return updates; 817cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 818cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 819cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 820cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void popBackStack() { 821990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount enqueueAction(new PopBackStackState(null, -1, 0), false); 822cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 823cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 824cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 825cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean popBackStackImmediate() { 826cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn checkStateLoss(); 827990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return popBackStackImmediate(null, -1, 0); 828cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 829cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 830cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 831380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton public void popBackStack(@Nullable final String name, final int flags) { 832990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount enqueueAction(new PopBackStackState(name, -1, flags), false); 833cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 834cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 835cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 836380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton public boolean popBackStackImmediate(@Nullable String name, int flags) { 837cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn checkStateLoss(); 838990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return popBackStackImmediate(name, -1, flags); 839cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 840cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 841cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 842cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void popBackStack(final int id, final int flags) { 843cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (id < 0) { 844cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn throw new IllegalArgumentException("Bad id: " + id); 845cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 846990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount enqueueAction(new PopBackStackState(null, id, flags), false); 847cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 848cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 849cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 850cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean popBackStackImmediate(int id, int flags) { 851cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn checkStateLoss(); 852990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount execPendingActions(); 853cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (id < 0) { 854cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn throw new IllegalArgumentException("Bad id: " + id); 855cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 856990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return popBackStackImmediate(null, id, flags); 857990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 858990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 859990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 860990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Used by all public popBackStackImmediate methods, this executes pending transactions and 861990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * returns true if the pop action did anything, regardless of what other pending 862990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * transactions did. 863990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 864990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @return true if the pop operation did anything or false otherwise. 865990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 866990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private boolean popBackStackImmediate(String name, int id, int flags) { 867990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount execPendingActions(); 868990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ensureExecReady(true); 869990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 870418738949305a8a0e30eba92c125c650048f9c50Adam Powell if (mPrimaryNav != null // We have a primary nav fragment 871418738949305a8a0e30eba92c125c650048f9c50Adam Powell && id < 0 // No valid id (since they're local) 872418738949305a8a0e30eba92c125c650048f9c50Adam Powell && name == null) { // no name to pop to (since they're local) 873418738949305a8a0e30eba92c125c650048f9c50Adam Powell final FragmentManager childManager = mPrimaryNav.peekChildFragmentManager(); 874418738949305a8a0e30eba92c125c650048f9c50Adam Powell if (childManager != null && childManager.popBackStackImmediate()) { 875418738949305a8a0e30eba92c125c650048f9c50Adam Powell // We did something, just not to this specific FragmentManager. Return true. 876418738949305a8a0e30eba92c125c650048f9c50Adam Powell return true; 877418738949305a8a0e30eba92c125c650048f9c50Adam Powell } 878418738949305a8a0e30eba92c125c650048f9c50Adam Powell } 879418738949305a8a0e30eba92c125c650048f9c50Adam Powell 880990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean executePop = popBackStackState(mTmpRecords, mTmpIsPop, name, id, flags); 881990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (executePop) { 882990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mExecutingActions = true; 883990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount try { 884fda5be2466024a656152015c45a7681361d399bbGeorge Mount removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop); 885990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } finally { 886990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount cleanupExec(); 887990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 888990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 889990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 890990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount doPendingDeferredStart(); 89190b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount burpActive(); 892990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return executePop; 893cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 894cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 895cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 896cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public int getBackStackEntryCount() { 897cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return mBackStack != null ? mBackStack.size() : 0; 898cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 899cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 900cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 901cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public BackStackEntry getBackStackEntryAt(int index) { 902cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return mBackStack.get(index); 903cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 904cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 905cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 906cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void addOnBackStackChangedListener(OnBackStackChangedListener listener) { 907cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStackChangeListeners == null) { 908cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackChangeListeners = new ArrayList<OnBackStackChangedListener>(); 909cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 910cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackChangeListeners.add(listener); 911cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 912cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 913cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 914cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void removeOnBackStackChangedListener(OnBackStackChangedListener listener) { 915cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStackChangeListeners != null) { 916cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackChangeListeners.remove(listener); 917cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 918cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 919cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 920cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 921cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void putFragment(Bundle bundle, String key, Fragment fragment) { 922cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (fragment.mIndex < 0) { 92313fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn throwException(new IllegalStateException("Fragment " + fragment 92413fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn + " is not currently in the FragmentManager")); 925cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 926cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn bundle.putInt(key, fragment.mIndex); 927cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 928cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 929cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 930380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @Nullable 931cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public Fragment getFragment(Bundle bundle, String key) { 932cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int index = bundle.getInt(key, -1); 933cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (index == -1) { 934cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 935cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 936cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mActive.get(index); 937cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f == null) { 9382b336307cf98ca5142db6736812178293d47c500Cyril Mottier throwException(new IllegalStateException("Fragment no longer exists for key " 93913fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn + key + ": index " + index)); 940cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 941cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return f; 942cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 943cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 944cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 9451af440bacb04c42ca18ad58cbcefa01b41c6792eGeorge Mount public List<Fragment> getFragments() { 946ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount if (mAdded.isEmpty()) { 94796221034e4a23a2abb83f772a0281bb197ac5ac0George Mount return Collections.EMPTY_LIST; 94896221034e4a23a2abb83f772a0281bb197ac5ac0George Mount } 94996221034e4a23a2abb83f772a0281bb197ac5ac0George Mount synchronized (mAdded) { 9501af440bacb04c42ca18ad58cbcefa01b41c6792eGeorge Mount return (List<Fragment>) mAdded.clone(); 951418738949305a8a0e30eba92c125c650048f9c50Adam Powell } 9523a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown } 9533a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown 95490b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount /** 95590b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount * This is used by FragmentController to get the Active fragments. 95690b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount * 95790b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount * @return A list of active fragments in the fragment manager, including those that are in the 95890b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount * back stack. 95990b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount */ 96090b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount List<Fragment> getActiveFragments() { 96190b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount if (mActive == null) { 96290b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount return null; 96390b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount } 96490b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount final int count = mActive.size(); 96590b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount ArrayList<Fragment> fragments = new ArrayList<>(count); 96690b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount for (int i = 0; i < count; i++) { 96790b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount fragments.add(mActive.valueAt(i)); 96890b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount } 96990b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount return fragments; 97090b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount } 97190b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount 97290b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount /** 97390b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount * Used by FragmentController to get the number of Active Fragments. 97490b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount * 97590b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount * @return The number of active fragments. 97690b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount */ 97790b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount int getActiveFragmentCount() { 97890b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount if (mActive == null) { 97990b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount return 0; 98090b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount } 98190b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount return mActive.size(); 98290b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount } 98390b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount 9843a1a7fff9873abbf8097c96f7654a459bf34f223Jeff Brown @Override 985380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @Nullable 9865c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn public Fragment.SavedState saveFragmentInstanceState(Fragment fragment) { 9875c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn if (fragment.mIndex < 0) { 98813fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn throwException( new IllegalStateException("Fragment " + fragment 98913fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn + " is not currently in the FragmentManager")); 9905c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 9915c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn if (fragment.mState > Fragment.INITIALIZING) { 9925c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn Bundle result = saveFragmentBasicState(fragment); 9935c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn return result != null ? new Fragment.SavedState(result) : null; 9945c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 9955c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn return null; 9965c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 9975c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn 9985c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn @Override 99901df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler public boolean isDestroyed() { 100001df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler return mDestroyed; 100101df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler } 100201df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler 100301df737703cceecc6b3a319ca0ee0bd64415f1cfTony Mantler @Override 1004cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public String toString() { 1005cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn StringBuilder sb = new StringBuilder(128); 1006cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn sb.append("FragmentManager{"); 1007cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn sb.append(Integer.toHexString(System.identityHashCode(this))); 1008cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn sb.append(" in "); 10090adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (mParent != null) { 10100adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn DebugUtils.buildShortClassTag(mParent, sb); 10110adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn } else { 1012d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy DebugUtils.buildShortClassTag(mHost, sb); 10130adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn } 1014cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn sb.append("}}"); 1015cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return sb.toString(); 1016cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1017cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1018cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn @Override 1019cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { 1020cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn String innerPrefix = prefix + " "; 1021cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1022cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int N; 1023cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mActive != null) { 1024cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn N = mActive.size(); 1025cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (N > 0) { 1026cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print("Active Fragments in "); 1027cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(Integer.toHexString(System.identityHashCode(this))); 1028cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.println(":"); 1029cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<N; i++) { 103090b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount Fragment f = mActive.valueAt(i); 1031cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" #"); writer.print(i); 1032cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(": "); writer.println(f); 1033cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f != null) { 1034cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.dump(innerPrefix, fd, writer, args); 1035cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1036cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1037cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1038cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1039cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1040ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount N = mAdded.size(); 1041ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount if (N > 0) { 1042ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount writer.print(prefix); writer.println("Added Fragments:"); 1043ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount for (int i = 0; i < N; i++) { 1044ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount Fragment f = mAdded.get(i); 1045ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount writer.print(prefix); 1046ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount writer.print(" #"); 1047ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount writer.print(i); 1048ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount writer.print(": "); 1049ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount writer.println(f.toString()); 1050cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1051cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1052cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1053cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mCreatedMenus != null) { 1054cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn N = mCreatedMenus.size(); 1055cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (N > 0) { 1056cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.println("Fragments Created Menus:"); 1057cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<N; i++) { 1058cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mCreatedMenus.get(i); 1059cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" #"); writer.print(i); 1060cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(": "); writer.println(f.toString()); 1061cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1062cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1063cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1064cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1065cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStack != null) { 1066cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn N = mBackStack.size(); 1067cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (N > 0) { 1068cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.println("Back Stack:"); 1069cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<N; i++) { 1070cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn BackStackRecord bs = mBackStack.get(i); 1071cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" #"); writer.print(i); 1072cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(": "); writer.println(bs.toString()); 1073cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn bs.dump(innerPrefix, fd, writer, args); 1074cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1075cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1076cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1077cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1078cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn synchronized (this) { 1079cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStackIndices != null) { 1080cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn N = mBackStackIndices.size(); 1081cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (N > 0) { 1082cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.println("Back Stack Indices:"); 1083cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<N; i++) { 1084cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn BackStackRecord bs = mBackStackIndices.get(i); 1085cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" #"); writer.print(i); 1086cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(": "); writer.println(bs); 1087cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1088cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1089cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1090cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1091cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mAvailBackStackIndices != null && mAvailBackStackIndices.size() > 0) { 1092cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print("mAvailBackStackIndices: "); 1093cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.println(Arrays.toString(mAvailBackStackIndices.toArray())); 1094cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1095cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1096cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1097cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mPendingActions != null) { 1098cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn N = mPendingActions.size(); 1099cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (N > 0) { 1100cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.println("Pending Actions:"); 1101cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<N; i++) { 1102990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount OpGenerator r = mPendingActions.get(i); 1103cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" #"); writer.print(i); 1104cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(": "); writer.println(r); 1105cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1106cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1107cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1108cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1109cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.println("FragmentManager misc state:"); 1110d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy writer.print(prefix); writer.print(" mHost="); writer.println(mHost); 11110adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn writer.print(prefix); writer.print(" mContainer="); writer.println(mContainer); 11120adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (mParent != null) { 11130adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn writer.print(prefix); writer.print(" mParent="); writer.println(mParent); 11140adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn } 1115cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" mCurState="); writer.print(mCurState); 1116cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(" mStateSaved="); writer.print(mStateSaved); 11170d429d5f5bb0d6197d5c7a24b5c0bb5bcd5db8cdIan Lake writer.print(" mStopped="); writer.print(mStopped); 1118cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(" mDestroyed="); writer.println(mDestroyed); 1119cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mNeedMenuInvalidate) { 1120cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" mNeedMenuInvalidate="); 1121cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.println(mNeedMenuInvalidate); 1122cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1123cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mNoTransactionsBecause != null) { 1124cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.print(prefix); writer.print(" mNoTransactionsBecause="); 1125cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn writer.println(mNoTransactionsBecause); 1126cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1127cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1128cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 11299277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn static final Interpolator DECELERATE_QUINT = new DecelerateInterpolator(2.5f); 11309277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn static final Interpolator DECELERATE_CUBIC = new DecelerateInterpolator(1.5f); 11319277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn static final Interpolator ACCELERATE_QUINT = new AccelerateInterpolator(2.5f); 11329277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn static final Interpolator ACCELERATE_CUBIC = new AccelerateInterpolator(1.5f); 1133dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 11349277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn static final int ANIM_DUR = 220; 1135dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 113615e593ea3575512d7072240d1db9d74fad8749a3George Mount static AnimationOrAnimator makeOpenCloseAnimation(Context context, float startScale, 11379277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn float endScale, float startAlpha, float endAlpha) { 11389277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn AnimationSet set = new AnimationSet(false); 11399277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn ScaleAnimation scale = new ScaleAnimation(startScale, endScale, startScale, endScale, 11409277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn Animation.RELATIVE_TO_SELF, .5f, Animation.RELATIVE_TO_SELF, .5f); 11419277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn scale.setInterpolator(DECELERATE_QUINT); 11429277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn scale.setDuration(ANIM_DUR); 11439277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn set.addAnimation(scale); 11449277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn AlphaAnimation alpha = new AlphaAnimation(startAlpha, endAlpha); 11459277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn alpha.setInterpolator(DECELERATE_CUBIC); 11469277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn alpha.setDuration(ANIM_DUR); 11479277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn set.addAnimation(alpha); 114815e593ea3575512d7072240d1db9d74fad8749a3George Mount return new AnimationOrAnimator(set); 11499277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn } 1150dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 115115e593ea3575512d7072240d1db9d74fad8749a3George Mount static AnimationOrAnimator makeFadeAnimation(Context context, float start, float end) { 11529277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn AlphaAnimation anim = new AlphaAnimation(start, end); 11539277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn anim.setInterpolator(DECELERATE_CUBIC); 11549277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn anim.setDuration(ANIM_DUR); 115515e593ea3575512d7072240d1db9d74fad8749a3George Mount return new AnimationOrAnimator(anim); 11569277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn } 115703526560f132021f8fd7290259762ab362d4d567Doris Liu 115815e593ea3575512d7072240d1db9d74fad8749a3George Mount AnimationOrAnimator loadAnimation(Fragment fragment, int transit, boolean enter, 1159cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int transitionStyle) { 116015e593ea3575512d7072240d1db9d74fad8749a3George Mount int nextAnim = fragment.getNextAnim(); 116115e593ea3575512d7072240d1db9d74fad8749a3George Mount Animation animation = fragment.onCreateAnimation(transit, enter, nextAnim); 116215e593ea3575512d7072240d1db9d74fad8749a3George Mount if (animation != null) { 116315e593ea3575512d7072240d1db9d74fad8749a3George Mount return new AnimationOrAnimator(animation); 116415e593ea3575512d7072240d1db9d74fad8749a3George Mount } 116515e593ea3575512d7072240d1db9d74fad8749a3George Mount 116615e593ea3575512d7072240d1db9d74fad8749a3George Mount Animator animator = fragment.onCreateAnimator(transit, enter, nextAnim); 116715e593ea3575512d7072240d1db9d74fad8749a3George Mount if (animator != null) { 116815e593ea3575512d7072240d1db9d74fad8749a3George Mount return new AnimationOrAnimator(animator); 116915e593ea3575512d7072240d1db9d74fad8749a3George Mount } 117015e593ea3575512d7072240d1db9d74fad8749a3George Mount 117115e593ea3575512d7072240d1db9d74fad8749a3George Mount if (nextAnim != 0) { 117215e593ea3575512d7072240d1db9d74fad8749a3George Mount String dir = mHost.getContext().getResources().getResourceTypeName(nextAnim); 117315e593ea3575512d7072240d1db9d74fad8749a3George Mount boolean isAnim = "anim".equals(dir); 117415e593ea3575512d7072240d1db9d74fad8749a3George Mount boolean successfulLoad = false; 117515e593ea3575512d7072240d1db9d74fad8749a3George Mount if (isAnim) { 117615e593ea3575512d7072240d1db9d74fad8749a3George Mount // try AnimationUtils first 117715e593ea3575512d7072240d1db9d74fad8749a3George Mount try { 117815e593ea3575512d7072240d1db9d74fad8749a3George Mount animation = AnimationUtils.loadAnimation(mHost.getContext(), nextAnim); 117915e593ea3575512d7072240d1db9d74fad8749a3George Mount if (animation != null) { 118015e593ea3575512d7072240d1db9d74fad8749a3George Mount return new AnimationOrAnimator(animation); 118115e593ea3575512d7072240d1db9d74fad8749a3George Mount } 118215e593ea3575512d7072240d1db9d74fad8749a3George Mount // A null animation may be returned and that is acceptable 118315e593ea3575512d7072240d1db9d74fad8749a3George Mount successfulLoad = true; // succeeded in loading animation, but it is null 118415e593ea3575512d7072240d1db9d74fad8749a3George Mount } catch (NotFoundException e) { 118515e593ea3575512d7072240d1db9d74fad8749a3George Mount throw e; // Rethrow it -- the resource should be found if it is provided. 118615e593ea3575512d7072240d1db9d74fad8749a3George Mount } catch (RuntimeException e) { 118715e593ea3575512d7072240d1db9d74fad8749a3George Mount // Other exceptions can occur when loading an Animator from AnimationUtils. 118815e593ea3575512d7072240d1db9d74fad8749a3George Mount } 118915e593ea3575512d7072240d1db9d74fad8749a3George Mount } 119015e593ea3575512d7072240d1db9d74fad8749a3George Mount if (!successfulLoad) { 119115e593ea3575512d7072240d1db9d74fad8749a3George Mount // try Animator 119215e593ea3575512d7072240d1db9d74fad8749a3George Mount try { 119315e593ea3575512d7072240d1db9d74fad8749a3George Mount animator = AnimatorInflater.loadAnimator(mHost.getContext(), nextAnim); 119415e593ea3575512d7072240d1db9d74fad8749a3George Mount if (animator != null) { 119515e593ea3575512d7072240d1db9d74fad8749a3George Mount return new AnimationOrAnimator(animator); 119615e593ea3575512d7072240d1db9d74fad8749a3George Mount } 119715e593ea3575512d7072240d1db9d74fad8749a3George Mount } catch (RuntimeException e) { 119815e593ea3575512d7072240d1db9d74fad8749a3George Mount if (isAnim) { 119915e593ea3575512d7072240d1db9d74fad8749a3George Mount // Rethrow it -- we already tried AnimationUtils and it failed. 120015e593ea3575512d7072240d1db9d74fad8749a3George Mount throw e; 120115e593ea3575512d7072240d1db9d74fad8749a3George Mount } 120215e593ea3575512d7072240d1db9d74fad8749a3George Mount // Otherwise, it is probably an animation resource 120315e593ea3575512d7072240d1db9d74fad8749a3George Mount animation = AnimationUtils.loadAnimation(mHost.getContext(), nextAnim); 120415e593ea3575512d7072240d1db9d74fad8749a3George Mount if (animation != null) { 120515e593ea3575512d7072240d1db9d74fad8749a3George Mount return new AnimationOrAnimator(animation); 120615e593ea3575512d7072240d1db9d74fad8749a3George Mount } 120715e593ea3575512d7072240d1db9d74fad8749a3George Mount } 1208cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1209cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1210dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1211cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (transit == 0) { 1212cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 1213cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1214dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1215cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int styleIndex = transitToStyleIndex(transit, enter); 1216cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (styleIndex < 0) { 1217cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 1218cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 121903526560f132021f8fd7290259762ab362d4d567Doris Liu 12209277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn switch (styleIndex) { 12219277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn case ANIM_STYLE_OPEN_ENTER: 1222d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy return makeOpenCloseAnimation(mHost.getContext(), 1.125f, 1.0f, 0, 1); 12239277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn case ANIM_STYLE_OPEN_EXIT: 1224d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy return makeOpenCloseAnimation(mHost.getContext(), 1.0f, .975f, 1, 0); 12259277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn case ANIM_STYLE_CLOSE_ENTER: 1226d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy return makeOpenCloseAnimation(mHost.getContext(), .975f, 1.0f, 0, 1); 12279277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn case ANIM_STYLE_CLOSE_EXIT: 1228d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy return makeOpenCloseAnimation(mHost.getContext(), 1.0f, 1.075f, 1, 0); 12299277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn case ANIM_STYLE_FADE_ENTER: 1230d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy return makeFadeAnimation(mHost.getContext(), 0, 1); 12319277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn case ANIM_STYLE_FADE_EXIT: 1232d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy return makeFadeAnimation(mHost.getContext(), 1, 0); 12339277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn } 1234dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 123515e593ea3575512d7072240d1db9d74fad8749a3George Mount // TODO: remove or fix transitionStyle -- it apparently never worked. 12368491eb62f621cd5de4b4caed839be09c77011f53Todd Kennedy if (transitionStyle == 0 && mHost.onHasWindowAnimations()) { 12378491eb62f621cd5de4b4caed839be09c77011f53Todd Kennedy transitionStyle = mHost.onGetWindowAnimations(); 1238cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1239cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (transitionStyle == 0) { 1240cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 1241cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1242dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1243cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn //TypedArray attrs = mActivity.obtainStyledAttributes(transitionStyle, 1244cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // com.android.internal.R.styleable.FragmentAnimation); 1245cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn //int anim = attrs.getResourceId(styleIndex, 0); 1246cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn //attrs.recycle(); 1247dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1248cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn //if (anim == 0) { 1249cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // return null; 1250cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn //} 1251dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1252cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn //return AnimatorInflater.loadAnimator(mActivity, anim); 1253cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 1254cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1255dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1256abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell public void performPendingDeferredStart(Fragment f) { 1257abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell if (f.mDeferStart) { 125879398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell if (mExecutingActions) { 125979398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell // Wait until we're done executing our pending transactions 126079398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell mHavePendingDeferredStart = true; 126179398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell return; 126279398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell } 1263abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell f.mDeferStart = false; 12645506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn moveToState(f, mCurState, 0, 0, false); 1265abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell } 1266abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell } 1267abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell 126803526560f132021f8fd7290259762ab362d4d567Doris Liu /** 126903526560f132021f8fd7290259762ab362d4d567Doris Liu * Sets the to be animated view on hardware layer during the animation. Note 127003526560f132021f8fd7290259762ab362d4d567Doris Liu * that calling this will replace any existing animation listener on the animation 127103526560f132021f8fd7290259762ab362d4d567Doris Liu * with a new one, as animations do not support more than one listeners. Therefore, 127203526560f132021f8fd7290259762ab362d4d567Doris Liu * animations that already have listeners should do the layer change operations 127303526560f132021f8fd7290259762ab362d4d567Doris Liu * in their existing listeners, rather than calling this function. 127403526560f132021f8fd7290259762ab362d4d567Doris Liu */ 127515e593ea3575512d7072240d1db9d74fad8749a3George Mount private static void setHWLayerAnimListenerIfAlpha(final View v, AnimationOrAnimator anim) { 127603526560f132021f8fd7290259762ab362d4d567Doris Liu if (v == null || anim == null) { 127703526560f132021f8fd7290259762ab362d4d567Doris Liu return; 127803526560f132021f8fd7290259762ab362d4d567Doris Liu } 127903526560f132021f8fd7290259762ab362d4d567Doris Liu if (shouldRunOnHWLayer(v, anim)) { 128015e593ea3575512d7072240d1db9d74fad8749a3George Mount if (anim.animator != null) { 128115e593ea3575512d7072240d1db9d74fad8749a3George Mount anim.animator.addListener(new AnimatorOnHWLayerIfNeededListener(v)); 128215e593ea3575512d7072240d1db9d74fad8749a3George Mount } else { 128315e593ea3575512d7072240d1db9d74fad8749a3George Mount AnimationListener originalListener = getAnimationListener(anim.animation); 128415e593ea3575512d7072240d1db9d74fad8749a3George Mount // If there's already a listener set on the animation, we need wrap the new listener 128515e593ea3575512d7072240d1db9d74fad8749a3George Mount // around the existing listener, so that they will both get animation listener 128615e593ea3575512d7072240d1db9d74fad8749a3George Mount // callbacks. 128715e593ea3575512d7072240d1db9d74fad8749a3George Mount v.setLayerType(View.LAYER_TYPE_HARDWARE, null); 128815e593ea3575512d7072240d1db9d74fad8749a3George Mount anim.animation.setAnimationListener(new AnimateOnHWLayerIfNeededListener(v, 128915e593ea3575512d7072240d1db9d74fad8749a3George Mount originalListener)); 1290d02828a3781590e76fe86f2bf4ae8fbff4f5e2bdDoris Liu } 129103526560f132021f8fd7290259762ab362d4d567Doris Liu } 129203526560f132021f8fd7290259762ab362d4d567Doris Liu } 129303526560f132021f8fd7290259762ab362d4d567Doris Liu 129415e593ea3575512d7072240d1db9d74fad8749a3George Mount /** 129515e593ea3575512d7072240d1db9d74fad8749a3George Mount * Returns an existing AnimationListener on an Animation or {@code null} if none exists. 129615e593ea3575512d7072240d1db9d74fad8749a3George Mount */ 129715e593ea3575512d7072240d1db9d74fad8749a3George Mount private static AnimationListener getAnimationListener(Animation animation) { 129815e593ea3575512d7072240d1db9d74fad8749a3George Mount AnimationListener originalListener = null; 129915e593ea3575512d7072240d1db9d74fad8749a3George Mount try { 130015e593ea3575512d7072240d1db9d74fad8749a3George Mount if (sAnimationListenerField == null) { 130115e593ea3575512d7072240d1db9d74fad8749a3George Mount sAnimationListenerField = Animation.class.getDeclaredField("mListener"); 130215e593ea3575512d7072240d1db9d74fad8749a3George Mount sAnimationListenerField.setAccessible(true); 130315e593ea3575512d7072240d1db9d74fad8749a3George Mount } 130415e593ea3575512d7072240d1db9d74fad8749a3George Mount originalListener = (AnimationListener) sAnimationListenerField.get(animation); 130515e593ea3575512d7072240d1db9d74fad8749a3George Mount } catch (NoSuchFieldException e) { 130615e593ea3575512d7072240d1db9d74fad8749a3George Mount Log.e(TAG, "No field with the name mListener is found in Animation class", e); 130715e593ea3575512d7072240d1db9d74fad8749a3George Mount } catch (IllegalAccessException e) { 130815e593ea3575512d7072240d1db9d74fad8749a3George Mount Log.e(TAG, "Cannot access Animation's mListener field", e); 130915e593ea3575512d7072240d1db9d74fad8749a3George Mount } 131015e593ea3575512d7072240d1db9d74fad8749a3George Mount return originalListener; 131115e593ea3575512d7072240d1db9d74fad8749a3George Mount } 131215e593ea3575512d7072240d1db9d74fad8749a3George Mount 1313fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell boolean isStateAtLeast(int state) { 1314fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell return mCurState >= state; 1315fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell } 1316fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell 1317b7a2c474fc66d5b7f2a57f2c212f8ac5a9e6de70Aurimas Liutikas @SuppressWarnings("ReferenceEquality") 13185506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn void moveToState(Fragment f, int newState, int transit, int transitionStyle, 13195506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn boolean keepActive) { 1320cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Fragments that are not currently added will sit in the onCreate() state. 132174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn if ((!f.mAdded || f.mDetached) && newState > Fragment.CREATED) { 1322cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn newState = Fragment.CREATED; 1323cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 13242c4b5dbfee5232bcbbcb74b84ce9147b62a9d789Dianne Hackborn if (f.mRemoving && newState > f.mState) { 13255a97188ba9e2fe80ef31c1bd269f3963c394c1b4George Mount if (f.mState == Fragment.INITIALIZING && f.isInBackStack()) { 13265a97188ba9e2fe80ef31c1bd269f3963c394c1b4George Mount // Allow the fragment to be created so that it can be saved later. 13275a97188ba9e2fe80ef31c1bd269f3963c394c1b4George Mount newState = Fragment.CREATED; 13285a97188ba9e2fe80ef31c1bd269f3963c394c1b4George Mount } else { 13295a97188ba9e2fe80ef31c1bd269f3963c394c1b4George Mount // While removing a fragment, we can't change it to a higher state. 13305a97188ba9e2fe80ef31c1bd269f3963c394c1b4George Mount newState = f.mState; 13315a97188ba9e2fe80ef31c1bd269f3963c394c1b4George Mount } 13322c4b5dbfee5232bcbbcb74b84ce9147b62a9d789Dianne Hackborn } 13336cafd27a3c89dfed10d7e226dc6168307513d4a6Adam Powell // Defer start if requested; don't allow it to move to STARTED or higher 13346cafd27a3c89dfed10d7e226dc6168307513d4a6Adam Powell // if it's not already started. 13356cafd27a3c89dfed10d7e226dc6168307513d4a6Adam Powell if (f.mDeferStart && f.mState < Fragment.STARTED && newState > Fragment.STOPPED) { 1336abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell newState = Fragment.STOPPED; 1337abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell } 133837149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell if (f.mState <= newState) { 13399277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn // For fragments that are created from a layout, when restoring from 13409277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn // state we don't want to allow them to be created until they are 13419277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn // being reloaded from the layout. 13429277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn if (f.mFromLayout && !f.mInLayout) { 13439277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn return; 1344dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas } 134515e593ea3575512d7072240d1db9d74fad8749a3George Mount if (f.getAnimatingAway() != null || f.getAnimator() != null) { 1346cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // The fragment is currently being animated... but! Now we 1347cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // want to move our state back up. Give up on waiting for the 1348cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // animation, move to whatever the final state should be once 1349cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // the animation is done, and then we can proceed from there. 1350990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.setAnimatingAway(null); 135115e593ea3575512d7072240d1db9d74fad8749a3George Mount f.setAnimator(null); 1352990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveToState(f, f.getStateAfterAnimating(), 0, 0, true); 1353cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1354cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn switch (f.mState) { 1355cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case Fragment.INITIALIZING: 135637149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell if (newState > Fragment.INITIALIZING) { 135737149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell if (DEBUG) Log.v(TAG, "moveto CREATED: " + f); 135837149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell if (f.mSavedFragmentState != null) { 135937149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mSavedFragmentState.setClassLoader(mHost.getContext() 136037149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell .getClassLoader()); 136137149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray( 136237149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell FragmentManagerImpl.VIEW_STATE_TAG); 136337149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mTarget = getFragment(f.mSavedFragmentState, 136437149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell FragmentManagerImpl.TARGET_STATE_TAG); 136537149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell if (f.mTarget != null) { 136637149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mTargetRequestCode = f.mSavedFragmentState.getInt( 136737149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0); 136837149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell } 136937149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mUserVisibleHint = f.mSavedFragmentState.getBoolean( 137037149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true); 137137149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell if (!f.mUserVisibleHint) { 137237149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mDeferStart = true; 137337149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell if (newState > Fragment.STOPPED) { 137437149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell newState = Fragment.STOPPED; 137537149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell } 137679398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell } 137779398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell } 1378a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell 137937149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mHost = mHost; 138037149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mParentFragment = mParent; 138137149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mFragmentManager = mParent != null 138237149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell ? mParent.mChildFragmentManager : mHost.getFragmentManagerImpl(); 1383a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell 1384a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell // If we have a target fragment, push it along to at least CREATED 1385a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell // so that this one can rely on it as an initialized dependency. 1386a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell if (f.mTarget != null) { 138796767975440de77e44a231e6ef66b374b1403bd0George Mount if (mActive.get(f.mTarget.mIndex) != f.mTarget) { 1388a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell throw new IllegalStateException("Fragment " + f 1389a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell + " declared target fragment " + f.mTarget 1390a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell + " that does not belong to this FragmentManager!"); 1391a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell } 1392a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell if (f.mTarget.mState < Fragment.CREATED) { 1393a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell moveToState(f.mTarget, Fragment.CREATED, 0, 0, true); 1394a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell } 1395a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell } 1396a4fd990846a60f3647445bf65980faad47b4cc68Adam Powell 139737149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell dispatchOnFragmentPreAttached(f, mHost.getContext(), false); 139837149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mCalled = false; 139937149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.onAttach(mHost.getContext()); 140037149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell if (!f.mCalled) { 140137149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell throw new SuperNotCalledException("Fragment " + f 140237149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell + " did not call through to super.onAttach()"); 140337149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell } 140437149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell if (f.mParentFragment == null) { 140537149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell mHost.onAttachFragment(f); 140637149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell } else { 140737149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mParentFragment.onAttachFragment(f); 140837149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell } 140937149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell dispatchOnFragmentAttached(f, mHost.getContext(), false); 14100adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn 1411e97d1f2defa08e9bff9d39d6157981e30407e90aGeorge Mount if (!f.mIsCreated) { 14121d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell dispatchOnFragmentPreCreated(f, f.mSavedFragmentState, false); 141337149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.performCreate(f.mSavedFragmentState); 141437149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell dispatchOnFragmentCreated(f, f.mSavedFragmentState, false); 1415cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 141637149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.restoreChildFragmentState(f.mSavedFragmentState); 141737149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mState = Fragment.CREATED; 1418cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 141937149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mRetaining = false; 1420cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1421b7a2c474fc66d5b7f2a57f2c212f8ac5a9e6de70Aurimas Liutikas // fall through 1422cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case Fragment.CREATED: 142337149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell // This is outside the if statement below on purpose; we want this to run 142437149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell // even if we do a moveToState from CREATED => *, CREATED => CREATED, and 142537149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell // * => CREATED as part of the case fallthrough above. 142637149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell ensureInflatedFragmentView(f); 142737149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell 1428cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (newState > Fragment.CREATED) { 1429e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f); 1430cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (!f.mFromLayout) { 1431cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ViewGroup container = null; 1432cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mContainerId != 0) { 143336bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell if (f.mContainerId == View.NO_ID) { 143436bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell throwException(new IllegalArgumentException( 143536bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell "Cannot create fragment " 143636bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell + f 143736bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell + " for a container view with no id")); 143836bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell } 143936bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell container = (ViewGroup) mContainer.onFindViewById(f.mContainerId); 1440cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (container == null && !f.mRestored) { 144136bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell String resName; 144236bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell try { 144336bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell resName = f.getResources().getResourceName(f.mContainerId); 144436bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell } catch (NotFoundException e) { 144536bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell resName = "unknown"; 144636bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell } 144713fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn throwException(new IllegalArgumentException( 144813fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn "No view found for id 0x" 144913fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn + Integer.toHexString(f.mContainerId) + " (" 145036bd1e9880a74cc53edef99040bbb24fc1cad909Adam Powell + resName 145113fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn + ") for fragment " + f)); 1452cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1453cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1454cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mContainer = container; 14558b60e88655f6d4191e55b1dd8706e4ae2ae21b04George Mount f.mView = f.performCreateView(f.performGetLayoutInflater( 14560adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.mSavedFragmentState), container, f.mSavedFragmentState); 1457cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mView != null) { 1458cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mInnerView = f.mView; 1459fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas f.mView.setSaveFromParentEnabled(false); 1460cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (container != null) { 1461cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn container.addView(f.mView); 1462990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1463990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.mHidden) { 1464990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.mView.setVisibility(View.GONE); 1465cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1466e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn f.onViewCreated(f.mView, f.mSavedFragmentState); 1467267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState, 1468267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell false); 1469d88ddfd4577e46829bf87124ad335d3cb82c3895George Mount // Only animate the view if it is visible. This is done after 1470d88ddfd4577e46829bf87124ad335d3cb82c3895George Mount // dispatchOnFragmentViewCreated in case visibility is changed 1471d88ddfd4577e46829bf87124ad335d3cb82c3895George Mount f.mIsNewlyAdded = (f.mView.getVisibility() == View.VISIBLE) 1472d88ddfd4577e46829bf87124ad335d3cb82c3895George Mount && f.mContainer != null; 1473cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 1474cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mInnerView = null; 1475cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1476cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 14770adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn 14780adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.performActivityCreated(f.mSavedFragmentState); 1479267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell dispatchOnFragmentActivityCreated(f, f.mSavedFragmentState, false); 1480e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (f.mView != null) { 14810adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.restoreViewState(f.mSavedFragmentState); 1482e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1483cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mSavedFragmentState = null; 1484cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1485b7a2c474fc66d5b7f2a57f2c212f8ac5a9e6de70Aurimas Liutikas // fall through 1486cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case Fragment.ACTIVITY_CREATED: 14879375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell if (newState > Fragment.ACTIVITY_CREATED) { 14889375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell f.mState = Fragment.STOPPED; 14899375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell } 1490b7a2c474fc66d5b7f2a57f2c212f8ac5a9e6de70Aurimas Liutikas // fall through 1491e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn case Fragment.STOPPED: 1492e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (newState > Fragment.STOPPED) { 1493cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "moveto STARTED: " + f); 14949c53b844bd525e6a04e17291efc38713893074cdDianne Hackborn f.performStart(); 1495267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell dispatchOnFragmentStarted(f, false); 1496cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1497b7a2c474fc66d5b7f2a57f2c212f8ac5a9e6de70Aurimas Liutikas // fall through 1498cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case Fragment.STARTED: 1499cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (newState > Fragment.STARTED) { 1500cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f); 15010adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.performResume(); 1502267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell dispatchOnFragmentResumed(f, false); 15034e6647fe2551985f33407acd712a4942b090207aDianne Hackborn f.mSavedFragmentState = null; 15044e6647fe2551985f33407acd712a4942b090207aDianne Hackborn f.mSavedViewState = null; 1505cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1506cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1507cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else if (f.mState > newState) { 1508cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn switch (f.mState) { 1509cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case Fragment.RESUMED: 1510cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (newState < Fragment.RESUMED) { 1511cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "movefrom RESUMED: " + f); 15120adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.performPause(); 1513267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell dispatchOnFragmentPaused(f, false); 1514cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1515b7a2c474fc66d5b7f2a57f2c212f8ac5a9e6de70Aurimas Liutikas // fall through 1516cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case Fragment.STARTED: 1517cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (newState < Fragment.STARTED) { 1518cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "movefrom STARTED: " + f); 1519cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.performStop(); 1520267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell dispatchOnFragmentStopped(f, false); 1521cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1522b7a2c474fc66d5b7f2a57f2c212f8ac5a9e6de70Aurimas Liutikas // fall through 1523e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn case Fragment.STOPPED: 1524218c1e661578e2a17928f7dbb590b43d1c79aeb7Dianne Hackborn if (newState < Fragment.STOPPED) { 1525218c1e661578e2a17928f7dbb590b43d1c79aeb7Dianne Hackborn if (DEBUG) Log.v(TAG, "movefrom STOPPED: " + f); 1526218c1e661578e2a17928f7dbb590b43d1c79aeb7Dianne Hackborn f.performReallyStop(); 1527218c1e661578e2a17928f7dbb590b43d1c79aeb7Dianne Hackborn } 1528b7a2c474fc66d5b7f2a57f2c212f8ac5a9e6de70Aurimas Liutikas // fall through 1529cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case Fragment.ACTIVITY_CREATED: 1530cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (newState < Fragment.ACTIVITY_CREATED) { 1531e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (DEBUG) Log.v(TAG, "movefrom ACTIVITY_CREATED: " + f); 1532cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mView != null) { 1533cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Need to save the current view state if not 1534cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // done already. 15358491eb62f621cd5de4b4caed839be09c77011f53Todd Kennedy if (mHost.onShouldSaveFragmentState(f) && f.mSavedViewState == null) { 1536cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn saveFragmentViewState(f); 1537cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1538cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 15399c53b844bd525e6a04e17291efc38713893074cdDianne Hackborn f.performDestroyView(); 1540267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell dispatchOnFragmentViewDestroyed(f, false); 1541cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mView != null && f.mContainer != null) { 1542a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount // Stop any current animations: 1543a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount f.mContainer.endViewTransition(f.mView); 1544e62545fdf58881a2d0426285648f71ce9323ca15George Mount f.mView.clearAnimation(); 154515e593ea3575512d7072240d1db9d74fad8749a3George Mount AnimationOrAnimator anim = null; 1546990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mCurState > Fragment.INITIALIZING && !mDestroyed 15470bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount && f.mView.getVisibility() == View.VISIBLE 15480bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount && f.mPostponedAlpha >= 0) { 15499277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn anim = loadAnimation(f, transit, false, 1550cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn transitionStyle); 1551cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 15520bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount f.mPostponedAlpha = 0; 1553cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (anim != null) { 155415e593ea3575512d7072240d1db9d74fad8749a3George Mount animateRemoveFragment(f, anim, newState); 1555cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 15568aa950177d9290b005f0817485f241ddc41c8026George Mount f.mContainer.removeView(f.mView); 1557cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1558cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mContainer = null; 1559cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mView = null; 1560cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mInnerView = null; 156137149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mInLayout = false; 1562cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1563b7a2c474fc66d5b7f2a57f2c212f8ac5a9e6de70Aurimas Liutikas // fall through 1564cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case Fragment.CREATED: 1565cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (newState < Fragment.CREATED) { 1566cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mDestroyed) { 156715e593ea3575512d7072240d1db9d74fad8749a3George Mount // The fragment's containing activity is 156815e593ea3575512d7072240d1db9d74fad8749a3George Mount // being destroyed, but this fragment is 156915e593ea3575512d7072240d1db9d74fad8749a3George Mount // currently animating away. Stop the 157015e593ea3575512d7072240d1db9d74fad8749a3George Mount // animation right now -- it is not needed, 157115e593ea3575512d7072240d1db9d74fad8749a3George Mount // and we can't wait any more on destroying 157215e593ea3575512d7072240d1db9d74fad8749a3George Mount // the fragment. 1573990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.getAnimatingAway() != null) { 1574990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount View v = f.getAnimatingAway(); 1575990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.setAnimatingAway(null); 1576cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn v.clearAnimation(); 157715e593ea3575512d7072240d1db9d74fad8749a3George Mount } else if (f.getAnimator() != null) { 157815e593ea3575512d7072240d1db9d74fad8749a3George Mount Animator animator = f.getAnimator(); 157915e593ea3575512d7072240d1db9d74fad8749a3George Mount f.setAnimator(null); 158015e593ea3575512d7072240d1db9d74fad8749a3George Mount animator.cancel(); 1581cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1582cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 158315e593ea3575512d7072240d1db9d74fad8749a3George Mount if (f.getAnimatingAway() != null || f.getAnimator() != null) { 1584cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // We are waiting for the fragment's view to finish 1585cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // animating away. Just make a note of the state 1586cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // the fragment now should move to once the animation 1587cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // is done. 1588990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.setStateAfterAnimating(newState); 15892c4b5dbfee5232bcbbcb74b84ce9147b62a9d789Dianne Hackborn newState = Fragment.CREATED; 1590cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 1591cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "movefrom CREATED: " + f); 1592cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (!f.mRetaining) { 15930adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.performDestroy(); 1594267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell dispatchOnFragmentDestroyed(f, false); 159520735a45289fdad3d5d31228992e0dccd3d5dd4fAdam Powell } else { 1596b054427688e7cf0475bec09da9a3fb7688881459Adam Powell f.mState = Fragment.INITIALIZING; 1597cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1598cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 1599916455675ddb34d0eb848b2355550268d82c3ce7Adam Powell f.performDetach(); 1600267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell dispatchOnFragmentDetached(f, false); 16015506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn if (!keepActive) { 16025506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn if (!f.mRetaining) { 16035506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn makeInactive(f); 16045506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn } else { 1605d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy f.mHost = null; 16066252d78085a07c9d6bb4645a4e8086bf23b0a49aTim Kilbourn f.mParentFragment = null; 16075506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn f.mFragmentManager = null; 16085506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn } 16092c4b5dbfee5232bcbbcb74b84ce9147b62a9d789Dianne Hackborn } 1610cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1611cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1612cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1613cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 161420735a45289fdad3d5d31228992e0dccd3d5dd4fAdam Powell 161520735a45289fdad3d5d31228992e0dccd3d5dd4fAdam Powell if (f.mState != newState) { 161620735a45289fdad3d5d31228992e0dccd3d5dd4fAdam Powell Log.w(TAG, "moveToState: Fragment state for " + f + " not updated inline; " 161720735a45289fdad3d5d31228992e0dccd3d5dd4fAdam Powell + "expected state " + newState + " found " + f.mState); 161820735a45289fdad3d5d31228992e0dccd3d5dd4fAdam Powell f.mState = newState; 161920735a45289fdad3d5d31228992e0dccd3d5dd4fAdam Powell } 1620cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1621dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 162215e593ea3575512d7072240d1db9d74fad8749a3George Mount /** 162315e593ea3575512d7072240d1db9d74fad8749a3George Mount * Animates the removal of a fragment with the given animator or animation. After animating, 162415e593ea3575512d7072240d1db9d74fad8749a3George Mount * the fragment's view will be removed from the hierarchy. 162515e593ea3575512d7072240d1db9d74fad8749a3George Mount * 162615e593ea3575512d7072240d1db9d74fad8749a3George Mount * @param fragment The fragment to animate out 162715e593ea3575512d7072240d1db9d74fad8749a3George Mount * @param anim The animator or animation to run on the fragment's view 162815e593ea3575512d7072240d1db9d74fad8749a3George Mount * @param newState The final state after animating. 162915e593ea3575512d7072240d1db9d74fad8749a3George Mount */ 163015e593ea3575512d7072240d1db9d74fad8749a3George Mount private void animateRemoveFragment(@NonNull final Fragment fragment, 163115e593ea3575512d7072240d1db9d74fad8749a3George Mount @NonNull AnimationOrAnimator anim, final int newState) { 163215e593ea3575512d7072240d1db9d74fad8749a3George Mount final View viewToAnimate = fragment.mView; 16336d8b13113aae9b68bec4441bdfe549f0a1d6b32eGeorge Mount final ViewGroup container = fragment.mContainer; 16346d8b13113aae9b68bec4441bdfe549f0a1d6b32eGeorge Mount container.startViewTransition(viewToAnimate); 163515e593ea3575512d7072240d1db9d74fad8749a3George Mount fragment.setStateAfterAnimating(newState); 163615e593ea3575512d7072240d1db9d74fad8749a3George Mount if (anim.animation != null) { 1637e62545fdf58881a2d0426285648f71ce9323ca15George Mount Animation animation = 1638e62545fdf58881a2d0426285648f71ce9323ca15George Mount new EndViewTransitionAnimator(anim.animation, container, viewToAnimate); 163915e593ea3575512d7072240d1db9d74fad8749a3George Mount fragment.setAnimatingAway(fragment.mView); 164015e593ea3575512d7072240d1db9d74fad8749a3George Mount AnimationListener listener = getAnimationListener(animation); 164115e593ea3575512d7072240d1db9d74fad8749a3George Mount animation.setAnimationListener(new AnimationListenerWrapper(listener) { 164215e593ea3575512d7072240d1db9d74fad8749a3George Mount @Override 164315e593ea3575512d7072240d1db9d74fad8749a3George Mount public void onAnimationEnd(Animation animation) { 164415e593ea3575512d7072240d1db9d74fad8749a3George Mount super.onAnimationEnd(animation); 1645e62545fdf58881a2d0426285648f71ce9323ca15George Mount 1646bad50a1424252621296ef611ee2f3e0f73711562George Mount // onAnimationEnd() comes during draw(), so there can still be some 1647bad50a1424252621296ef611ee2f3e0f73711562George Mount // draw events happening after this call. We don't want to detach 1648bad50a1424252621296ef611ee2f3e0f73711562George Mount // the view until after the onAnimationEnd() 1649bad50a1424252621296ef611ee2f3e0f73711562George Mount container.post(new Runnable() { 1650bad50a1424252621296ef611ee2f3e0f73711562George Mount @Override 1651bad50a1424252621296ef611ee2f3e0f73711562George Mount public void run() { 1652bad50a1424252621296ef611ee2f3e0f73711562George Mount if (fragment.getAnimatingAway() != null) { 1653bad50a1424252621296ef611ee2f3e0f73711562George Mount fragment.setAnimatingAway(null); 1654bad50a1424252621296ef611ee2f3e0f73711562George Mount moveToState(fragment, fragment.getStateAfterAnimating(), 0, 0, 1655bad50a1424252621296ef611ee2f3e0f73711562George Mount false); 1656bad50a1424252621296ef611ee2f3e0f73711562George Mount } 1657bad50a1424252621296ef611ee2f3e0f73711562George Mount } 1658bad50a1424252621296ef611ee2f3e0f73711562George Mount }); 165915e593ea3575512d7072240d1db9d74fad8749a3George Mount } 166015e593ea3575512d7072240d1db9d74fad8749a3George Mount }); 166115e593ea3575512d7072240d1db9d74fad8749a3George Mount setHWLayerAnimListenerIfAlpha(viewToAnimate, anim); 166215e593ea3575512d7072240d1db9d74fad8749a3George Mount fragment.mView.startAnimation(animation); 166315e593ea3575512d7072240d1db9d74fad8749a3George Mount } else { 16645ee728a9f41b6ea2bbdc332b2ebe2255f3bdbfb7George Mount Animator animator = anim.animator; 166515e593ea3575512d7072240d1db9d74fad8749a3George Mount fragment.setAnimator(anim.animator); 166615e593ea3575512d7072240d1db9d74fad8749a3George Mount animator.addListener(new AnimatorListenerAdapter() { 166715e593ea3575512d7072240d1db9d74fad8749a3George Mount @Override 166815e593ea3575512d7072240d1db9d74fad8749a3George Mount public void onAnimationEnd(Animator anim) { 16695ee728a9f41b6ea2bbdc332b2ebe2255f3bdbfb7George Mount container.endViewTransition(viewToAnimate); 16705ee728a9f41b6ea2bbdc332b2ebe2255f3bdbfb7George Mount // If an animator ends immediately, we can just pretend there is no animation. 16715ee728a9f41b6ea2bbdc332b2ebe2255f3bdbfb7George Mount // When that happens the the fragment's view won't have been removed yet. 16725ee728a9f41b6ea2bbdc332b2ebe2255f3bdbfb7George Mount Animator animator = fragment.getAnimator(); 16735ee728a9f41b6ea2bbdc332b2ebe2255f3bdbfb7George Mount fragment.setAnimator(null); 16745ee728a9f41b6ea2bbdc332b2ebe2255f3bdbfb7George Mount if (animator != null && container.indexOfChild(viewToAnimate) < 0) { 16755ee728a9f41b6ea2bbdc332b2ebe2255f3bdbfb7George Mount moveToState(fragment, fragment.getStateAfterAnimating(), 0, 0, false); 167615e593ea3575512d7072240d1db9d74fad8749a3George Mount } 167715e593ea3575512d7072240d1db9d74fad8749a3George Mount } 167815e593ea3575512d7072240d1db9d74fad8749a3George Mount }); 167915e593ea3575512d7072240d1db9d74fad8749a3George Mount animator.setTarget(fragment.mView); 168015e593ea3575512d7072240d1db9d74fad8749a3George Mount setHWLayerAnimListenerIfAlpha(fragment.mView, anim); 168115e593ea3575512d7072240d1db9d74fad8749a3George Mount animator.start(); 168215e593ea3575512d7072240d1db9d74fad8749a3George Mount } 168315e593ea3575512d7072240d1db9d74fad8749a3George Mount } 168415e593ea3575512d7072240d1db9d74fad8749a3George Mount 1685cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn void moveToState(Fragment f) { 16865506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn moveToState(f, mCurState, 0, 0, false); 1687cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1688cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 168937149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell void ensureInflatedFragmentView(Fragment f) { 169037149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell if (f.mFromLayout && !f.mPerformedCreateView) { 1691bae5c5f73f48516194fdf5c7cfb6b3b7d9878537George Mount f.mView = f.performCreateView(f.performGetLayoutInflater( 169237149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mSavedFragmentState), null, f.mSavedFragmentState); 169337149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell if (f.mView != null) { 169437149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mInnerView = f.mView; 1695fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas f.mView.setSaveFromParentEnabled(false); 169637149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell if (f.mHidden) f.mView.setVisibility(View.GONE); 169737149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.onViewCreated(f.mView, f.mSavedFragmentState); 169837149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState, false); 169937149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell } else { 170037149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell f.mInnerView = null; 170137149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell } 170237149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell } 170337149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell } 170437149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell 1705990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 1706990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Fragments that have been shown or hidden don't have their visibility changed or 1707990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * animations run during the {@link #showFragment(Fragment)} or {@link #hideFragment(Fragment)} 1708990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * calls. After fragments are brought to their final state in 1709990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@link #moveFragmentToExpectedState(Fragment)} the fragments that have been shown or 1710990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * hidden must have their visibility changed and their animations started here. 1711990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 1712990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param fragment The fragment with mHiddenChanged = true that should change its View's 1713990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * visibility and start the show or hide animation. 1714990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 1715990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount void completeShowHideFragment(final Fragment fragment) { 1716990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (fragment.mView != null) { 171715e593ea3575512d7072240d1db9d74fad8749a3George Mount AnimationOrAnimator anim = loadAnimation(fragment, fragment.getNextTransition(), 1718990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount !fragment.mHidden, fragment.getNextTransitionStyle()); 171915e593ea3575512d7072240d1db9d74fad8749a3George Mount if (anim != null && anim.animator != null) { 172015e593ea3575512d7072240d1db9d74fad8749a3George Mount anim.animator.setTarget(fragment.mView); 172115e593ea3575512d7072240d1db9d74fad8749a3George Mount if (fragment.mHidden) { 172215e593ea3575512d7072240d1db9d74fad8749a3George Mount if (fragment.isHideReplaced()) { 172315e593ea3575512d7072240d1db9d74fad8749a3George Mount fragment.setHideReplaced(false); 172415e593ea3575512d7072240d1db9d74fad8749a3George Mount } else { 172515e593ea3575512d7072240d1db9d74fad8749a3George Mount final ViewGroup container = fragment.mContainer; 172615e593ea3575512d7072240d1db9d74fad8749a3George Mount final View animatingView = fragment.mView; 172715e593ea3575512d7072240d1db9d74fad8749a3George Mount container.startViewTransition(animatingView); 172815e593ea3575512d7072240d1db9d74fad8749a3George Mount // Delay the actual hide operation until the animation finishes, 172915e593ea3575512d7072240d1db9d74fad8749a3George Mount // otherwise the fragment will just immediately disappear 173015e593ea3575512d7072240d1db9d74fad8749a3George Mount anim.animator.addListener(new AnimatorListenerAdapter() { 173115e593ea3575512d7072240d1db9d74fad8749a3George Mount @Override 173215e593ea3575512d7072240d1db9d74fad8749a3George Mount public void onAnimationEnd(Animator animation) { 173315e593ea3575512d7072240d1db9d74fad8749a3George Mount container.endViewTransition(animatingView); 173415e593ea3575512d7072240d1db9d74fad8749a3George Mount animation.removeListener(this); 173515e593ea3575512d7072240d1db9d74fad8749a3George Mount if (fragment.mView != null) { 173615e593ea3575512d7072240d1db9d74fad8749a3George Mount fragment.mView.setVisibility(View.GONE); 173715e593ea3575512d7072240d1db9d74fad8749a3George Mount } 173815e593ea3575512d7072240d1db9d74fad8749a3George Mount } 173915e593ea3575512d7072240d1db9d74fad8749a3George Mount }); 174015e593ea3575512d7072240d1db9d74fad8749a3George Mount } 174115e593ea3575512d7072240d1db9d74fad8749a3George Mount } else { 174215e593ea3575512d7072240d1db9d74fad8749a3George Mount fragment.mView.setVisibility(View.VISIBLE); 174315e593ea3575512d7072240d1db9d74fad8749a3George Mount } 1744990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount setHWLayerAnimListenerIfAlpha(fragment.mView, anim); 174515e593ea3575512d7072240d1db9d74fad8749a3George Mount anim.animator.start(); 174615e593ea3575512d7072240d1db9d74fad8749a3George Mount } else { 174715e593ea3575512d7072240d1db9d74fad8749a3George Mount if (anim != null) { 174815e593ea3575512d7072240d1db9d74fad8749a3George Mount setHWLayerAnimListenerIfAlpha(fragment.mView, anim); 174915e593ea3575512d7072240d1db9d74fad8749a3George Mount fragment.mView.startAnimation(anim.animation); 175015e593ea3575512d7072240d1db9d74fad8749a3George Mount anim.animation.start(); 175115e593ea3575512d7072240d1db9d74fad8749a3George Mount } 175215e593ea3575512d7072240d1db9d74fad8749a3George Mount final int visibility = fragment.mHidden && !fragment.isHideReplaced() 175315e593ea3575512d7072240d1db9d74fad8749a3George Mount ? View.GONE 175415e593ea3575512d7072240d1db9d74fad8749a3George Mount : View.VISIBLE; 175515e593ea3575512d7072240d1db9d74fad8749a3George Mount fragment.mView.setVisibility(visibility); 175615e593ea3575512d7072240d1db9d74fad8749a3George Mount if (fragment.isHideReplaced()) { 175715e593ea3575512d7072240d1db9d74fad8749a3George Mount fragment.setHideReplaced(false); 175815e593ea3575512d7072240d1db9d74fad8749a3George Mount } 1759667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount } 1760990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1761990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (fragment.mAdded && fragment.mHasMenu && fragment.mMenuVisible) { 1762990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mNeedMenuInvalidate = true; 1763990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1764990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.mHiddenChanged = false; 1765990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.onHiddenChanged(fragment.mHidden); 1766cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1767dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1768990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 1769990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Moves a fragment to its expected final state or the fragment manager's state, depending 1770990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * on whether the fragment manager's state is raised properly. 1771990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 1772990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param f The fragment to change. 1773990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 1774990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount void moveFragmentToExpectedState(Fragment f) { 1775990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f == null) { 1776990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return; 1777990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1778990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int nextState = mCurState; 1779990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.mRemoving) { 1780990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.isInBackStack()) { 178140e1750a5ed6cca1efb47e10af4db19abecd9fd5George Mount nextState = Math.min(nextState, Fragment.CREATED); 1782990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } else { 178340e1750a5ed6cca1efb47e10af4db19abecd9fd5George Mount nextState = Math.min(nextState, Fragment.INITIALIZING); 1784990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1785cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1786990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveToState(f, nextState, f.getNextTransition(), f.getNextTransitionStyle(), false); 17870adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn 1788990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.mView != null) { 1789990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Move the view if it is out of order 1790990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Fragment underFragment = findFragmentUnder(f); 1791990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (underFragment != null) { 1792990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final View underView = underFragment.mView; 1793990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // make sure this fragment is in the right order. 1794990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final ViewGroup container = f.mContainer; 1795990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int underIndex = container.indexOfChild(underView); 1796990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int viewIndex = container.indexOfChild(f.mView); 1797990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (viewIndex < underIndex) { 1798990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount container.removeViewAt(viewIndex); 1799990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount container.addView(f.mView, underIndex); 1800990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1801990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1802990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.mIsNewlyAdded && f.mContainer != null) { 1803990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Make it visible and run the animations 18049d359be2fec790cf02c3201c89ff37d425d35058Aurimas Liutikas if (f.mPostponedAlpha > 0f) { 18050bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount f.mView.setAlpha(f.mPostponedAlpha); 18060bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount } 18070bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount f.mPostponedAlpha = 0f; 1808990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.mIsNewlyAdded = false; 1809990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // run animations: 181015e593ea3575512d7072240d1db9d74fad8749a3George Mount AnimationOrAnimator anim = loadAnimation(f, f.getNextTransition(), true, 1811990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount f.getNextTransitionStyle()); 1812990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (anim != null) { 1813990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount setHWLayerAnimListenerIfAlpha(f.mView, anim); 181415e593ea3575512d7072240d1db9d74fad8749a3George Mount if (anim.animation != null) { 181515e593ea3575512d7072240d1db9d74fad8749a3George Mount f.mView.startAnimation(anim.animation); 181615e593ea3575512d7072240d1db9d74fad8749a3George Mount } else { 181715e593ea3575512d7072240d1db9d74fad8749a3George Mount anim.animator.setTarget(f.mView); 181815e593ea3575512d7072240d1db9d74fad8749a3George Mount anim.animator.start(); 181915e593ea3575512d7072240d1db9d74fad8749a3George Mount } 1820990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1821990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1822990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1823990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f.mHiddenChanged) { 1824990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount completeShowHideFragment(f); 1825990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1826990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1827990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 182877f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount /** 182977f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount * Changes the state of the fragment manager to {@code newState}. If the fragment manager 183077f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount * changes state or {@code always} is {@code true}, any fragments within it have their 183177f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount * states updated as well. 183277f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount * 183377f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount * @param newState The new state for the fragment manager 183477f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount * @param always If {@code true}, all fragments update their state, even 183577f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount * if {@code newState} matches the current fragment manager's state. 183677f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount */ 183777f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount void moveToState(int newState, boolean always) { 1838990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mHost == null && newState != Fragment.INITIALIZING) { 1839990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount throw new IllegalStateException("No activity"); 1840cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 18410adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn 184277f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount if (!always && newState == mCurState) { 184377f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount return; 184477f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount } 184577f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount 1846cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mCurState = newState; 1847990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 1848cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mActive != null) { 1849990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 1850990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Must add them in the proper order. mActive fragments may be out of order 1851ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount final int numAdded = mAdded.size(); 1852ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount for (int i = 0; i < numAdded; i++) { 1853ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount Fragment f = mAdded.get(i); 1854ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount moveFragmentToExpectedState(f); 1855990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 1856990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 1857990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Now iterate through all active fragments. These will include those that are removed 1858990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // and detached. 1859990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int numActive = mActive.size(); 1860990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numActive; i++) { 186190b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount Fragment f = mActive.valueAt(i); 1862990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (f != null && (f.mRemoving || f.mDetached) && !f.mIsNewlyAdded) { 1863990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveFragmentToExpectedState(f); 1864cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1865cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1866cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 186798179e0c692f8812d961e2e1d8a7ef086ea234f5Ian Lake startPendingDeferredFragments(); 1868abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell 1869d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy if (mNeedMenuInvalidate && mHost != null && mCurState == Fragment.RESUMED) { 18708491eb62f621cd5de4b4caed839be09c77011f53Todd Kennedy mHost.onSupportInvalidateOptionsMenu(); 1871cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mNeedMenuInvalidate = false; 1872cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1873cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1874cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1875abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell 1876abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell void startPendingDeferredFragments() { 18771199ae7067cdf8cf3eb30c057a61ae71a0aea1e5Adam Powell if (mActive == null) return; 18781199ae7067cdf8cf3eb30c057a61ae71a0aea1e5Adam Powell 1879abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell for (int i=0; i<mActive.size(); i++) { 188090b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount Fragment f = mActive.valueAt(i); 1881abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell if (f != null) { 1882abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell performPendingDeferredStart(f); 1883abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell } 1884abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell } 1885abc968f1eba800c34a4008deb43b015da5d23a5fAdam Powell } 1886dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1887cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn void makeActive(Fragment f) { 1888cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mIndex >= 0) { 1889cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return; 1890cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1891dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 189290b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount f.setIndex(mNextFragmentIndex++, mParent); 189390b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount if (mActive == null) { 189490b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount mActive = new SparseArray<>(); 1895cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 189690b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount mActive.put(f.mIndex, f); 1897be2c79d9a5439922030d2a3846c81c61f0e16912Dianne Hackborn if (DEBUG) Log.v(TAG, "Allocated fragment index " + f); 1898cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1899dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1900cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn void makeInactive(Fragment f) { 1901cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mIndex < 0) { 1902cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return; 1903cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1904dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1905be2c79d9a5439922030d2a3846c81c61f0e16912Dianne Hackborn if (DEBUG) Log.v(TAG, "Freeing fragment index " + f); 190690b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount // Don't remove yet. That happens in burpActive(). This prevents 190790b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount // concurrent modification while iterating over mActive 190890b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount mActive.put(f.mIndex, null); 190990b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount 19109c53b844bd525e6a04e17291efc38713893074cdDianne Hackborn f.initState(); 1911cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1912dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1913cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void addFragment(Fragment fragment, boolean moveToStateNow) { 1914cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "add: " + fragment); 1915e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn makeActive(fragment); 1916e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (!fragment.mDetached) { 19173a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn if (mAdded.contains(fragment)) { 19183a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn throw new IllegalStateException("Fragment already added: " + fragment); 19193a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn } 192096221034e4a23a2abb83f772a0281bb197ac5ac0George Mount synchronized (mAdded) { 192196221034e4a23a2abb83f772a0281bb197ac5ac0George Mount mAdded.add(fragment); 192296221034e4a23a2abb83f772a0281bb197ac5ac0George Mount } 1923e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn fragment.mAdded = true; 1924e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn fragment.mRemoving = false; 1925990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (fragment.mView == null) { 1926990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.mHiddenChanged = false; 1927990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 19282a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn if (fragment.mHasMenu && fragment.mMenuVisible) { 1929e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn mNeedMenuInvalidate = true; 1930e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1931e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (moveToStateNow) { 1932e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn moveToState(fragment); 1933e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1934cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1935cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1936dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1937990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void removeFragment(Fragment fragment) { 1938cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "remove: " + fragment + " nesting=" + fragment.mBackStackNesting); 1939e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn final boolean inactive = !fragment.isInBackStack(); 1940e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (!fragment.mDetached || inactive) { 1941ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount synchronized (mAdded) { 1942ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount mAdded.remove(fragment); 1943464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn } 19442a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn if (fragment.mHasMenu && fragment.mMenuVisible) { 1945e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn mNeedMenuInvalidate = true; 1946e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1947e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn fragment.mAdded = false; 1948e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn fragment.mRemoving = true; 1949cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1950cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1951dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1952990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 1953990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Marks a fragment as hidden to be later animated in with 1954990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@link #completeShowHideFragment(Fragment)}. 1955990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 1956990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param fragment The fragment to be shown. 1957990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 1958990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void hideFragment(Fragment fragment) { 1959cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "hide: " + fragment); 1960cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (!fragment.mHidden) { 1961cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fragment.mHidden = true; 1962990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Toggle hidden changed so that if a fragment goes through show/hide/show 1963990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // it doesn't go through the animation. 1964990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.mHiddenChanged = !fragment.mHiddenChanged; 1965cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1966cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1967dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1968990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 1969990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Marks a fragment as shown to be later animated in with 1970990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@link #completeShowHideFragment(Fragment)}. 1971990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 1972990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param fragment The fragment to be shown. 1973990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 1974990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void showFragment(Fragment fragment) { 1975cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "show: " + fragment); 1976cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (fragment.mHidden) { 1977cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fragment.mHidden = false; 1978990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Toggle hidden changed so that if a fragment goes through show/hide/show 1979990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // it doesn't go through the animation. 1980990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.mHiddenChanged = !fragment.mHiddenChanged; 1981cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1982cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 1983dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 1984990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void detachFragment(Fragment fragment) { 1985e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (DEBUG) Log.v(TAG, "detach: " + fragment); 1986e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (!fragment.mDetached) { 1987e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn fragment.mDetached = true; 1988e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (fragment.mAdded) { 1989e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn // We are not already in back stack, so need to remove the fragment. 1990ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount if (DEBUG) Log.v(TAG, "remove from detach: " + fragment); 1991ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount synchronized (mAdded) { 1992ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount mAdded.remove(fragment); 1993464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn } 19942a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn if (fragment.mHasMenu && fragment.mMenuVisible) { 1995e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn mNeedMenuInvalidate = true; 1996e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1997e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn fragment.mAdded = false; 1998e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 1999e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 2000e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 2001e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn 2002990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void attachFragment(Fragment fragment) { 2003e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (DEBUG) Log.v(TAG, "attach: " + fragment); 2004e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (fragment.mDetached) { 2005e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn fragment.mDetached = false; 2006e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn if (!fragment.mAdded) { 20073a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn if (mAdded.contains(fragment)) { 20083a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn throw new IllegalStateException("Fragment already added: " + fragment); 20093a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn } 20103a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn if (DEBUG) Log.v(TAG, "add from attach: " + fragment); 201196221034e4a23a2abb83f772a0281bb197ac5ac0George Mount synchronized (mAdded) { 201296221034e4a23a2abb83f772a0281bb197ac5ac0George Mount mAdded.add(fragment); 201396221034e4a23a2abb83f772a0281bb197ac5ac0George Mount } 2014e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn fragment.mAdded = true; 20152a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn if (fragment.mHasMenu && fragment.mMenuVisible) { 2016e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn mNeedMenuInvalidate = true; 2017e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 2018e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 2019e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 2020e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn } 2021e4417c91a0bb2fba42a0aaa99edcca1b238af21aDianne Hackborn 202290ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas @Override 2023380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @Nullable 2024cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public Fragment findFragmentById(int id) { 2025ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount // First look through added fragments. 2026ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount for (int i = mAdded.size() - 1; i >= 0; i--) { 2027ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount Fragment f = mAdded.get(i); 2028ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount if (f != null && f.mFragmentId == id) { 2029ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount return f; 2030cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2031464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn } 2032464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mActive != null) { 2033cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Now for any known fragment. 2034cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=mActive.size()-1; i>=0; i--) { 203590b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount Fragment f = mActive.valueAt(i); 2036cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f != null && f.mFragmentId == id) { 2037cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return f; 2038cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2039cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2040cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2041cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 2042cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 204390ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas 204490ac236504c1a4cac7e91f1ffc523334f2a8f399Aurimas Liutikas @Override 2045380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @Nullable 2046380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton public Fragment findFragmentByTag(@Nullable String tag) { 2047ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount if (tag != null) { 2048cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // First look through added fragments. 2049cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=mAdded.size()-1; i>=0; i--) { 2050cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mAdded.get(i); 2051cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f != null && tag.equals(f.mTag)) { 2052cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return f; 2053cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2054cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2055464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn } 2056464b6f3c93dda03359ec2d37c8205065922f2994Dianne Hackborn if (mActive != null && tag != null) { 2057cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Now for any known fragment. 2058cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=mActive.size()-1; i>=0; i--) { 205990b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount Fragment f = mActive.valueAt(i); 2060cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f != null && tag.equals(f.mTag)) { 2061cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return f; 2062cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2063cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2064cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2065cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 2066cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2067dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2068cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public Fragment findFragmentByWho(String who) { 2069cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mActive != null && who != null) { 2070cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=mActive.size()-1; i>=0; i--) { 207190b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount Fragment f = mActive.valueAt(i); 20720adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn if (f != null && (f=f.findFragmentByWho(who)) != null) { 2073cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return f; 2074cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2075cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2076cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2077cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 2078cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2079dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2080cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn private void checkStateLoss() { 20810d429d5f5bb0d6197d5c7a24b5c0bb5bcd5db8cdIan Lake if (isStateSaved()) { 2082cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn throw new IllegalStateException( 2083cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn "Can not perform this action after onSaveInstanceState"); 2084cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2085cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mNoTransactionsBecause != null) { 2086cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn throw new IllegalStateException( 2087cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn "Can not perform this action inside of " + mNoTransactionsBecause); 2088cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2089cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2090cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 209147844337986f365dae294fb434de0c0f7f8df5dbGeorge Mount @Override 20925e2b030b851bde2b4569104a01b4acf6960327a6Adam Powell public boolean isStateSaved() { 20930d429d5f5bb0d6197d5c7a24b5c0bb5bcd5db8cdIan Lake // See saveAllState() for the explanation of this. We do this for 20940d429d5f5bb0d6197d5c7a24b5c0bb5bcd5db8cdIan Lake // all platform versions, to keep our behavior more consistent between 20950d429d5f5bb0d6197d5c7a24b5c0bb5bcd5db8cdIan Lake // them. 20960d429d5f5bb0d6197d5c7a24b5c0bb5bcd5db8cdIan Lake return mStateSaved || mStopped; 20975e2b030b851bde2b4569104a01b4acf6960327a6Adam Powell } 20985e2b030b851bde2b4569104a01b4acf6960327a6Adam Powell 2099ab6e5dbcc6e05994ebb4257478c54f54085b9aa6Alan Viverette /** 2100ab6e5dbcc6e05994ebb4257478c54f54085b9aa6Alan Viverette * Adds an action to the queue of pending actions. 2101ab6e5dbcc6e05994ebb4257478c54f54085b9aa6Alan Viverette * 2102ab6e5dbcc6e05994ebb4257478c54f54085b9aa6Alan Viverette * @param action the action to add 2103ab6e5dbcc6e05994ebb4257478c54f54085b9aa6Alan Viverette * @param allowStateLoss whether to allow loss of state information 2104ab6e5dbcc6e05994ebb4257478c54f54085b9aa6Alan Viverette * @throws IllegalStateException if the activity has been destroyed 2105ab6e5dbcc6e05994ebb4257478c54f54085b9aa6Alan Viverette */ 2106990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void enqueueAction(OpGenerator action, boolean allowStateLoss) { 2107cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (!allowStateLoss) { 2108cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn checkStateLoss(); 2109cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2110cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn synchronized (this) { 2111d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy if (mDestroyed || mHost == null) { 2112875d9733f354fc93e72c7e8d849c9b5333950183George Mount if (allowStateLoss) { 2113875d9733f354fc93e72c7e8d849c9b5333950183George Mount // This FragmentManager isn't attached, so drop the entire transaction. 2114875d9733f354fc93e72c7e8d849c9b5333950183George Mount return; 2115875d9733f354fc93e72c7e8d849c9b5333950183George Mount } 2116cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn throw new IllegalStateException("Activity has been destroyed"); 2117cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2118cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mPendingActions == null) { 2119990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mPendingActions = new ArrayList<>(); 2120cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2121cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mPendingActions.add(action); 2122990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount scheduleCommit(); 2123990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2124990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2125990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2126990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2127990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Schedules the execution when one hasn't been scheduled already. This should happen 2128990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * the first time {@link #enqueueAction(OpGenerator, boolean)} is called or when 2129990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * a postponed transaction has been started with 2130990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@link Fragment#startPostponedEnterTransition()} 2131990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2132990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void scheduleCommit() { 2133990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount synchronized (this) { 2134990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean postponeReady = 2135990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mPostponedTransactions != null && !mPostponedTransactions.isEmpty(); 2136990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean pendingReady = mPendingActions != null && mPendingActions.size() == 1; 2137990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (postponeReady || pendingReady) { 2138d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy mHost.getHandler().removeCallbacks(mExecCommit); 2139d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy mHost.getHandler().post(mExecCommit); 2140cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2141cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2142cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2143dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2144cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public int allocBackStackIndex(BackStackRecord bse) { 2145cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn synchronized (this) { 2146cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mAvailBackStackIndices == null || mAvailBackStackIndices.size() <= 0) { 2147cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStackIndices == null) { 2148cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackIndices = new ArrayList<BackStackRecord>(); 2149cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2150cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int index = mBackStackIndices.size(); 2151cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Setting back stack index " + index + " to " + bse); 2152cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackIndices.add(bse); 2153cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return index; 2154cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2155cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 2156cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int index = mAvailBackStackIndices.remove(mAvailBackStackIndices.size()-1); 2157cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Adding back stack index " + index + " with " + bse); 2158cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackIndices.set(index, bse); 2159cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return index; 2160cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2161cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2162cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2163cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2164cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void setBackStackIndex(int index, BackStackRecord bse) { 2165cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn synchronized (this) { 2166cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStackIndices == null) { 2167cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackIndices = new ArrayList<BackStackRecord>(); 2168cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2169cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int N = mBackStackIndices.size(); 2170cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (index < N) { 2171cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Setting back stack index " + index + " to " + bse); 2172cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackIndices.set(index, bse); 2173cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 2174cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn while (N < index) { 2175cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackIndices.add(null); 2176cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mAvailBackStackIndices == null) { 2177cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAvailBackStackIndices = new ArrayList<Integer>(); 2178cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2179cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Adding available back stack index " + N); 2180cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAvailBackStackIndices.add(N); 2181cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn N++; 2182cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2183cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Adding back stack index " + index + " with " + bse); 2184cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackIndices.add(bse); 2185cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2186cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2187cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2188cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2189cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void freeBackStackIndex(int index) { 2190cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn synchronized (this) { 2191cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackIndices.set(index, null); 2192cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mAvailBackStackIndices == null) { 2193cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAvailBackStackIndices = new ArrayList<Integer>(); 2194cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2195cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Freeing back stack index " + index); 2196cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mAvailBackStackIndices.add(index); 2197cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2198cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2199cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2200990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2201990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Broken out from exec*, this prepares for gathering and executing operations. 2202990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 2203990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param allowStateLoss true if state loss should be ignored or false if it should be 2204990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * checked. 2205990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2206990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void ensureExecReady(boolean allowStateLoss) { 2207e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell if (mExecutingActions) { 2208e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell throw new IllegalStateException("FragmentManager is already executing transactions"); 2209e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell } 2210e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell 2211104bca7256dba76376aa7921517b2568e09c7bacIan Lake if (mHost == null) { 2212104bca7256dba76376aa7921517b2568e09c7bacIan Lake throw new IllegalStateException("Fragment host has been destroyed"); 2213104bca7256dba76376aa7921517b2568e09c7bacIan Lake } 2214104bca7256dba76376aa7921517b2568e09c7bacIan Lake 2215e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell if (Looper.myLooper() != mHost.getHandler().getLooper()) { 2216e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell throw new IllegalStateException("Must be called from main thread of fragment host"); 2217e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell } 2218e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell 2219e880475b147312ca62bed05bbeb37ec820d693aeAdam Powell if (!allowStateLoss) { 2220e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell checkStateLoss(); 2221e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell } 2222e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell 2223990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mTmpRecords == null) { 2224990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mTmpRecords = new ArrayList<>(); 2225990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mTmpIsPop = new ArrayList<>(); 2226990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 22270a849aafc735476e572e97c78be0ce912adfe512George Mount mExecutingActions = true; 22280a849aafc735476e572e97c78be0ce912adfe512George Mount try { 22290a849aafc735476e572e97c78be0ce912adfe512George Mount executePostponedTransaction(null, null); 22300a849aafc735476e572e97c78be0ce912adfe512George Mount } finally { 22310a849aafc735476e572e97c78be0ce912adfe512George Mount mExecutingActions = false; 22320a849aafc735476e572e97c78be0ce912adfe512George Mount } 2233990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2234990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2235990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void execSingleAction(OpGenerator action, boolean allowStateLoss) { 2236875d9733f354fc93e72c7e8d849c9b5333950183George Mount if (allowStateLoss && (mHost == null || mDestroyed)) { 2237875d9733f354fc93e72c7e8d849c9b5333950183George Mount // This FragmentManager isn't attached, so drop the entire transaction. 2238875d9733f354fc93e72c7e8d849c9b5333950183George Mount return; 2239875d9733f354fc93e72c7e8d849c9b5333950183George Mount } 2240990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ensureExecReady(allowStateLoss); 2241990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (action.generateOps(mTmpRecords, mTmpIsPop)) { 2242990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mExecutingActions = true; 2243990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount try { 2244fda5be2466024a656152015c45a7681361d399bbGeorge Mount removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop); 2245990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } finally { 2246990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount cleanupExec(); 2247990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2248990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2249e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell 2250e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell doPendingDeferredStart(); 225190b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount burpActive(); 2252e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell } 2253e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell 2254cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn /** 2255990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Broken out of exec*, this cleans up the mExecutingActions and the temporary structures 2256990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * used in executing operations. 2257990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2258990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void cleanupExec() { 2259990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mExecutingActions = false; 2260990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mTmpIsPop.clear(); 2261990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mTmpRecords.clear(); 2262990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2263990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2264990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2265cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Only call from main thread! 2266cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */ 2267cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean execPendingActions() { 2268990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ensureExecReady(true); 2269990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2270990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean didSomething = false; 2271990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) { 2272990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mExecutingActions = true; 2273990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount try { 2274fda5be2466024a656152015c45a7681361d399bbGeorge Mount removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop); 2275990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } finally { 2276990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount cleanupExec(); 2277990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2278990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount didSomething = true; 2279cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2280dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2281990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount doPendingDeferredStart(); 228290b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount burpActive(); 2283990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2284990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return didSomething; 2285990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2286990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2287990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2288990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Complete the execution of transactions that have previously been postponed, but are 2289990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * now ready. 2290990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2291990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void executePostponedTransaction(ArrayList<BackStackRecord> records, 2292990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Boolean> isRecordPop) { 2293990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int numPostponed = mPostponedTransactions == null ? 0 : mPostponedTransactions.size(); 2294990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numPostponed; i++) { 2295990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount StartEnterTransitionListener listener = mPostponedTransactions.get(i); 2296990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (records != null && !listener.mIsBack) { 2297990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int index = records.indexOf(listener.mRecord); 2298990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (index != -1 && isRecordPop.get(index)) { 2299990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount listener.cancelTransaction(); 2300990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount continue; 2301990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2302990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2303990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (listener.isReady() || (records != null 2304990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount && listener.mRecord.interactsWith(records, 0, records.size()))) { 2305990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mPostponedTransactions.remove(i); 2306990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount i--; 2307990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount numPostponed--; 2308990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int index; 2309990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (records != null && !listener.mIsBack 2310990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount && (index = records.indexOf(listener.mRecord)) != -1 2311990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount && isRecordPop.get(index)) { 2312990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // This is popping a postponed transaction 2313990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount listener.cancelTransaction(); 2314990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } else { 2315990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount listener.completeTransaction(); 2316990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2317990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2318cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2319990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2320cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2321990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2322fda5be2466024a656152015c45a7681361d399bbGeorge Mount * Remove redundant BackStackRecord operations and executes them. This method merges operations 2323fda5be2466024a656152015c45a7681361d399bbGeorge Mount * of proximate records that allow reordering. See 2324fda5be2466024a656152015c45a7681361d399bbGeorge Mount * {@link FragmentTransaction#setReorderingAllowed(boolean)}. 2325990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * <p> 2326990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * For example, a transaction that adds to the back stack and then another that pops that 2327fda5be2466024a656152015c45a7681361d399bbGeorge Mount * back stack record will be optimized to remove the unnecessary operation. 2328990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * <p> 2329990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Likewise, two transactions committed that are executed at the same time will be optimized 2330fda5be2466024a656152015c45a7681361d399bbGeorge Mount * to remove the redundant operations as well as two pop operations executed together. 2331990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 2332990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param records The records pending execution 2333990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param isRecordPop The direction that these records are being run. 2334990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2335fda5be2466024a656152015c45a7681361d399bbGeorge Mount private void removeRedundantOperationsAndExecute(ArrayList<BackStackRecord> records, 2336990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Boolean> isRecordPop) { 2337990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (records == null || records.isEmpty()) { 2338990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return; 2339990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2340990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2341990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (isRecordPop == null || records.size() != isRecordPop.size()) { 2342990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount throw new IllegalStateException("Internal error with the back stack records"); 2343990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2344990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2345990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Force start of any postponed transactions that interact with scheduled transactions: 2346990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount executePostponedTransaction(records, isRecordPop); 2347990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2348990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int numRecords = records.size(); 2349990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int startIndex = 0; 2350990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int recordNum = 0; recordNum < numRecords; recordNum++) { 2351fda5be2466024a656152015c45a7681361d399bbGeorge Mount final boolean canReorder = records.get(recordNum).mReorderingAllowed; 2352fda5be2466024a656152015c45a7681361d399bbGeorge Mount if (!canReorder) { 2353990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // execute all previous transactions 2354990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (startIndex != recordNum) { 2355990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount executeOpsTogether(records, isRecordPop, startIndex, recordNum); 2356990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2357fda5be2466024a656152015c45a7681361d399bbGeorge Mount // execute all pop operations that don't allow reordering together or 2358fda5be2466024a656152015c45a7681361d399bbGeorge Mount // one add operation 2359fda5be2466024a656152015c45a7681361d399bbGeorge Mount int reorderingEnd = recordNum + 1; 2360f284a0dc76d73ef7132dd1187a43d9a7ad0258deGeorge Mount if (isRecordPop.get(recordNum)) { 2361fda5be2466024a656152015c45a7681361d399bbGeorge Mount while (reorderingEnd < numRecords 2362fda5be2466024a656152015c45a7681361d399bbGeorge Mount && isRecordPop.get(reorderingEnd) 2363fda5be2466024a656152015c45a7681361d399bbGeorge Mount && !records.get(reorderingEnd).mReorderingAllowed) { 2364fda5be2466024a656152015c45a7681361d399bbGeorge Mount reorderingEnd++; 2365990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2366990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2367fda5be2466024a656152015c45a7681361d399bbGeorge Mount executeOpsTogether(records, isRecordPop, recordNum, reorderingEnd); 2368fda5be2466024a656152015c45a7681361d399bbGeorge Mount startIndex = reorderingEnd; 2369fda5be2466024a656152015c45a7681361d399bbGeorge Mount recordNum = reorderingEnd - 1; 2370990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2371990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2372990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (startIndex != numRecords) { 2373990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount executeOpsTogether(records, isRecordPop, startIndex, numRecords); 2374990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2375990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2376990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2377990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2378fda5be2466024a656152015c45a7681361d399bbGeorge Mount * Executes a subset of a list of BackStackRecords, all of which either allow reordering or 2379fda5be2466024a656152015c45a7681361d399bbGeorge Mount * do not allow ordering. 2380fda5be2466024a656152015c45a7681361d399bbGeorge Mount * @param records A list of BackStackRecords that are to be executed 2381990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param isRecordPop The direction that these records are being run. 2382fda5be2466024a656152015c45a7681361d399bbGeorge Mount * @param startIndex The index of the first record in <code>records</code> to be executed 2383fda5be2466024a656152015c45a7681361d399bbGeorge Mount * @param endIndex One more than the final record index in <code>records</code> to executed. 2384990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2385990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void executeOpsTogether(ArrayList<BackStackRecord> records, 2386990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) { 2387fda5be2466024a656152015c45a7681361d399bbGeorge Mount final boolean allowReordering = records.get(startIndex).mReorderingAllowed; 2388990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean addToBackStack = false; 2389990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mTmpAddedFragments == null) { 2390990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mTmpAddedFragments = new ArrayList<>(); 2391990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } else { 2392990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mTmpAddedFragments.clear(); 2393990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2394ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount mTmpAddedFragments.addAll(mAdded); 2395418738949305a8a0e30eba92c125c650048f9c50Adam Powell Fragment oldPrimaryNav = getPrimaryNavigationFragment(); 2396990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int recordNum = startIndex; recordNum < endIndex; recordNum++) { 2397990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final BackStackRecord record = records.get(recordNum); 2398990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final boolean isPop = isRecordPop.get(recordNum); 2399990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (!isPop) { 2400418738949305a8a0e30eba92c125c650048f9c50Adam Powell oldPrimaryNav = record.expandOps(mTmpAddedFragments, oldPrimaryNav); 24011ff374ad7efdabdd103bf0ad3352a4bb184acc78George Mount } else { 24021ff374ad7efdabdd103bf0ad3352a4bb184acc78George Mount oldPrimaryNav = record.trackAddedFragmentsInPop(mTmpAddedFragments, oldPrimaryNav); 2403990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2404990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount addToBackStack = addToBackStack || record.mAddToBackStack; 2405990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2406990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mTmpAddedFragments.clear(); 2407990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2408fda5be2466024a656152015c45a7681361d399bbGeorge Mount if (!allowReordering) { 2409990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTransition.startTransitions(this, records, isRecordPop, startIndex, endIndex, 2410990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount false); 2411990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2412990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount executeOps(records, isRecordPop, startIndex, endIndex); 2413cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2414990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int postponeIndex = endIndex; 2415fda5be2466024a656152015c45a7681361d399bbGeorge Mount if (allowReordering) { 24160bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount ArraySet<Fragment> addedFragments = new ArraySet<>(); 24170bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount addAddedFragments(addedFragments); 2418990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount postponeIndex = postponePostponableTransactions(records, isRecordPop, 24190bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount startIndex, endIndex, addedFragments); 24200bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount makeRemovedFragmentsInvisible(addedFragments); 2421990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2422990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2423fda5be2466024a656152015c45a7681361d399bbGeorge Mount if (postponeIndex != startIndex && allowReordering) { 2424990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // need to run something now 2425990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTransition.startTransitions(this, records, isRecordPop, startIndex, 2426990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount postponeIndex, true); 242777f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount moveToState(mCurState, true); 2428990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2429990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2430990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int recordNum = startIndex; recordNum < endIndex; recordNum++) { 2431990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final BackStackRecord record = records.get(recordNum); 2432990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final boolean isPop = isRecordPop.get(recordNum); 2433990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (isPop && record.mIndex >= 0) { 2434990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount freeBackStackIndex(record.mIndex); 2435990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount record.mIndex = -1; 2436990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 24375e2b030b851bde2b4569104a01b4acf6960327a6Adam Powell record.runOnCommitRunnables(); 2438990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2439990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (addToBackStack) { 2440990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount reportBackStackChanged(); 2441990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2442990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2443dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2444990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 24450bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount * Any fragments that were removed because they have been postponed should have their views 244615e593ea3575512d7072240d1db9d74fad8749a3George Mount * made invisible by setting their alpha to 0. 24470bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount * 24480bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount * @param fragments The fragments that were added during operation execution. Only the ones 24490bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount * that are no longer added will have their alpha changed. 24500bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount */ 24510bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount private void makeRemovedFragmentsInvisible(ArraySet<Fragment> fragments) { 24520bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount final int numAdded = fragments.size(); 24530bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount for (int i = 0; i < numAdded; i++) { 24540bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount final Fragment fragment = fragments.valueAt(i); 24550bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount if (!fragment.mAdded) { 24560bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount final View view = fragment.getView(); 24579d359be2fec790cf02c3201c89ff37d425d35058Aurimas Liutikas fragment.mPostponedAlpha = view.getAlpha(); 24589d359be2fec790cf02c3201c89ff37d425d35058Aurimas Liutikas view.setAlpha(0f); 24590bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount } 24600bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount } 24610bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount } 24620bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount 24630bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount /** 2464990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Examine all transactions and determine which ones are marked as postponed. Those will 2465990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * have their operations rolled back and moved to the end of the record list (up to endIndex). 2466990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * It will also add the postponed transaction to the queue. 2467990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 2468990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param records A list of BackStackRecords that should be checked. 2469990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param isRecordPop The direction that these records are being run. 2470990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param startIndex The index of the first record in <code>records</code> to be checked 2471990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param endIndex One more than the final record index in <code>records</code> to be checked. 2472990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @return The index of the first postponed transaction or endIndex if no transaction was 2473990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * postponed. 2474990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2475990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private int postponePostponableTransactions(ArrayList<BackStackRecord> records, 24760bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount ArrayList<Boolean> isRecordPop, int startIndex, int endIndex, 24770bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount ArraySet<Fragment> added) { 2478990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int postponeIndex = endIndex; 2479990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = endIndex - 1; i >= startIndex; i--) { 2480990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final BackStackRecord record = records.get(i); 2481990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final boolean isPop = isRecordPop.get(i); 2482990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean isPostponed = record.isPostponed() 2483990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount && !record.interactsWith(records, i + 1, endIndex); 2484990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (isPostponed) { 2485990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mPostponedTransactions == null) { 2486990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mPostponedTransactions = new ArrayList<>(); 2487990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2488990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount StartEnterTransitionListener listener = 2489990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount new StartEnterTransitionListener(record, isPop); 2490990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mPostponedTransactions.add(listener); 2491990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount record.setOnStartPostponedListener(listener); 2492990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2493990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // roll back the transaction 2494990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (isPop) { 2495990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount record.executeOps(); 2496990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } else { 24970846eb5fb991505a85c8288b52d7fa58ebade9b2George Mount record.executePopOps(false); 2498cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2499dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2500990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // move to the end 2501990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount postponeIndex--; 2502990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (i != postponeIndex) { 2503990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount records.remove(i); 2504990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount records.add(postponeIndex, record); 2505cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2506990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2507990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // different views may be visible now 25080bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount addAddedFragments(added); 2509cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2510990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2511990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return postponeIndex; 2512990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2513dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2514990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2515990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * When a postponed transaction is ready to be started, this completes the transaction, 2516990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * removing, hiding, or showing views as well as starting the animations and transitions. 2517990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * <p> 2518990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@code runtransitions} is set to false when the transaction postponement was interrupted 2519990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * abnormally -- normally by a new transaction being started that affects the postponed 2520990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * transaction. 2521990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 2522990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param record The transaction to run 2523990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param isPop true if record is popping or false if it is adding 2524990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param runTransitions true if the fragment transition should be run or false otherwise. 2525990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param moveToState true if the state should be changed after executing the operations. 2526990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * This is false when the transaction is canceled when a postponed 2527990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * transaction is popped. 2528990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2529990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void completeExecute(BackStackRecord record, boolean isPop, boolean runTransitions, 2530990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean moveToState) { 25318ab31e242e509b289fa6a577426b21cc45b95ef5George Mount if (isPop) { 25328ab31e242e509b289fa6a577426b21cc45b95ef5George Mount record.executePopOps(moveToState); 25338ab31e242e509b289fa6a577426b21cc45b95ef5George Mount } else { 25348ab31e242e509b289fa6a577426b21cc45b95ef5George Mount record.executeOps(); 25358ab31e242e509b289fa6a577426b21cc45b95ef5George Mount } 2536990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<BackStackRecord> records = new ArrayList<>(1); 2537990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Boolean> isRecordPop = new ArrayList<>(1); 2538990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount records.add(record); 2539990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount isRecordPop.add(isPop); 2540990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (runTransitions) { 2541990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentTransition.startTransitions(this, records, isRecordPop, 0, 1, true); 2542990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2543990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (moveToState) { 254477f11e921b9be7645b74a33b2ca11c1c4e24fbabGeorge Mount moveToState(mCurState, true); 25450bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount } 25460bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount 25470bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount if (mActive != null) { 2548990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int numActive = mActive.size(); 2549990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numActive; i++) { 2550990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Allow added fragments to be removed during the pop since we aren't going 2551990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // to move them to the final state with moveToState(mCurState). 255290b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount Fragment fragment = mActive.valueAt(i); 25530bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount if (fragment != null && fragment.mView != null && fragment.mIsNewlyAdded 2554990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount && record.interactsWith(fragment.mContainerId)) { 25559d359be2fec790cf02c3201c89ff37d425d35058Aurimas Liutikas if (fragment.mPostponedAlpha > 0) { 25560bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount fragment.mView.setAlpha(fragment.mPostponedAlpha); 25570bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount } 25580bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount if (moveToState) { 25590bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount fragment.mPostponedAlpha = 0; 25600bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount } else { 25610bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount fragment.mPostponedAlpha = -1; 25620bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount fragment.mIsNewlyAdded = false; 25630bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount } 2564990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2565cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2566cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2567990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2568dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2569990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2570990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Find a fragment within the fragment's container whose View should be below the passed 2571990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * fragment. {@code null} is returned when the fragment has no View or if there should be 2572990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * no fragment with a View below the given fragment. 2573990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 2574990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * As an example, if mAdded has two Fragments with Views sharing the same container: 2575990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * FragmentA 2576990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * FragmentB 2577990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 2578990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Then, when processing FragmentB, FragmentA will be returned. If, however, FragmentA 2579990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * had no View, null would be returned. 2580990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 2581990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param f The fragment that may be on top of another fragment. 2582990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @return The fragment with a View under f, if one exists or null if f has no View or 2583990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * there are no fragments with Views in the same container. 2584990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2585990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private Fragment findFragmentUnder(Fragment f) { 2586990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final ViewGroup container = f.mContainer; 2587990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final View view = f.mView; 2588e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell 2589990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (container == null || view == null) { 2590990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return null; 2591990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2592990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2593990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int fragmentIndex = mAdded.indexOf(f); 2594990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = fragmentIndex - 1; i >= 0; i--) { 2595990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Fragment underFragment = mAdded.get(i); 2596990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (underFragment.mContainer == container && underFragment.mView != null) { 2597990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // Found the fragment under this one 2598990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return underFragment; 2599990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2600990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2601990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return null; 2602990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2603990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2604990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2605990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Run the operations in the BackStackRecords, either to push or pop. 2606990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 2607990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param records The list of records whose operations should be run. 2608990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param isRecordPop The direction that these records are being run. 2609990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param startIndex The index of the first entry in records to run. 2610990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param endIndex One past the index of the final entry in records to run. 2611990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2612990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private static void executeOps(ArrayList<BackStackRecord> records, 2613990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) { 2614990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = startIndex; i < endIndex; i++) { 2615990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final BackStackRecord record = records.get(i); 2616990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final boolean isPop = isRecordPop.get(i); 2617990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (isPop) { 261837e785570b316db48ae8843d101f383899ea4d61George Mount record.bumpBackStackNesting(-1); 26190846eb5fb991505a85c8288b52d7fa58ebade9b2George Mount // Only execute the add operations at the end of 26200846eb5fb991505a85c8288b52d7fa58ebade9b2George Mount // all transactions. 26210846eb5fb991505a85c8288b52d7fa58ebade9b2George Mount boolean moveToState = i == (endIndex - 1); 26220846eb5fb991505a85c8288b52d7fa58ebade9b2George Mount record.executePopOps(moveToState); 2623990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } else { 262437e785570b316db48ae8843d101f383899ea4d61George Mount record.bumpBackStackNesting(1); 2625990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount record.executeOps(); 2626990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2627990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2628990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2629990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2630990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2631990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Ensure that fragments that are added are moved to at least the CREATED state. 26320bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount * Any newly-added Views are inserted into {@code added} so that the Transaction can be 26330bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount * postponed with {@link Fragment#postponeEnterTransition()}. They will later be made 26340bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount * invisible (by setting their alpha to 0) if they have been removed when postponed. 2635990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 26360bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount private void addAddedFragments(ArraySet<Fragment> added) { 2637990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mCurState < Fragment.CREATED) { 2638990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return; 2639990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2640990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // We want to leave the fragment in the started state 2641990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int state = Math.min(mCurState, Fragment.STARTED); 2642ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount final int numAdded = mAdded.size(); 2643990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numAdded; i++) { 2644990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Fragment fragment = mAdded.get(i); 2645990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (fragment.mState < state) { 2646990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount moveToState(fragment, state, fragment.getNextAnim(), fragment.getNextTransition(), 2647990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount false); 2648990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (fragment.mView != null && !fragment.mHidden && fragment.mIsNewlyAdded) { 26490bb3f19c91311de0b6619c7728a7bcc1f6863132George Mount added.add(fragment); 2650990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2651990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2652990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2653990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2654990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2655990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2656990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Starts all postponed transactions regardless of whether they are ready or not. 2657990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2658990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void forcePostponedTransactions() { 2659990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mPostponedTransactions != null) { 2660990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount while (!mPostponedTransactions.isEmpty()) { 2661990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mPostponedTransactions.remove(0).completeTransaction(); 2662990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2663990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2664990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2665990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2666990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2667990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Ends the animations of fragments so that they immediately reach the end state. 2668990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * This is used prior to saving the state so that the correct state is saved. 2669990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2670990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private void endAnimatingAwayFragments() { 2671990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int numFragments = mActive == null ? 0 : mActive.size(); 2672990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numFragments; i++) { 267390b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount Fragment fragment = mActive.valueAt(i); 267415e593ea3575512d7072240d1db9d74fad8749a3George Mount if (fragment != null) { 267515e593ea3575512d7072240d1db9d74fad8749a3George Mount if (fragment.getAnimatingAway() != null) { 267615e593ea3575512d7072240d1db9d74fad8749a3George Mount // Give up waiting for the animation and just end it. 267715e593ea3575512d7072240d1db9d74fad8749a3George Mount final int stateAfterAnimating = fragment.getStateAfterAnimating(); 267815e593ea3575512d7072240d1db9d74fad8749a3George Mount final View animatingAway = fragment.getAnimatingAway(); 267915e593ea3575512d7072240d1db9d74fad8749a3George Mount Animation animation = animatingAway.getAnimation(); 268015e593ea3575512d7072240d1db9d74fad8749a3George Mount if (animation != null) { 268115e593ea3575512d7072240d1db9d74fad8749a3George Mount animation.cancel(); 268215e593ea3575512d7072240d1db9d74fad8749a3George Mount // force-clear the animation, as Animation#cancel() doesn't work prior to N, 268315e593ea3575512d7072240d1db9d74fad8749a3George Mount // and will instead cause the animation to infinitely loop 268415e593ea3575512d7072240d1db9d74fad8749a3George Mount animatingAway.clearAnimation(); 268515e593ea3575512d7072240d1db9d74fad8749a3George Mount } 26866d8b13113aae9b68bec4441bdfe549f0a1d6b32eGeorge Mount fragment.setAnimatingAway(null); 268715e593ea3575512d7072240d1db9d74fad8749a3George Mount moveToState(fragment, stateAfterAnimating, 0, 0, false); 268815e593ea3575512d7072240d1db9d74fad8749a3George Mount } else if (fragment.getAnimator() != null) { 268915e593ea3575512d7072240d1db9d74fad8749a3George Mount fragment.getAnimator().end(); 26909b07983005689872240dee2084dec3520f95eb5aGeorge Mount } 2691990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2692990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2693990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2694990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2695990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 2696990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Adds all records in the pending actions to records and whether they are add or pop 2697990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * operations to isPop. After executing, the pending actions will be empty. 2698990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 2699990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param records All pending actions will generate BackStackRecords added to this. 2700990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * This contains the transactions, in order, to execute. 2701990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param isPop All pending actions will generate booleans to add to this. This contains 2702990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * an entry for each entry in records to indicate whether or not it is a 2703990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * pop action. 2704990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 2705990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private boolean generateOpsForPendingActions(ArrayList<BackStackRecord> records, 2706990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Boolean> isPop) { 2707418738949305a8a0e30eba92c125c650048f9c50Adam Powell boolean didSomething = false; 2708990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount synchronized (this) { 2709990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mPendingActions == null || mPendingActions.size() == 0) { 2710990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return false; 2711990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2712990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 2713418738949305a8a0e30eba92c125c650048f9c50Adam Powell final int numActions = mPendingActions.size(); 2714990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numActions; i++) { 2715418738949305a8a0e30eba92c125c650048f9c50Adam Powell didSomething |= mPendingActions.get(i).generateOps(records, isPop); 2716990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2717990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mPendingActions.clear(); 2718990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mHost.getHandler().removeCallbacks(mExecCommit); 2719990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 2720418738949305a8a0e30eba92c125c650048f9c50Adam Powell return didSomething; 2721e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell } 2722e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell 2723e1fad6fb0ee83d7f2dad3ec3dca6641a425e7244Adam Powell void doPendingDeferredStart() { 272479398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell if (mHavePendingDeferredStart) { 272598179e0c692f8812d961e2e1d8a7ef086ea234f5Ian Lake mHavePendingDeferredStart = false; 272698179e0c692f8812d961e2e1d8a7ef086ea234f5Ian Lake startPendingDeferredFragments(); 272779398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell } 2728cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 272979398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell 2730cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn void reportBackStackChanged() { 2731cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStackChangeListeners != null) { 2732cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<mBackStackChangeListeners.size(); i++) { 2733cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStackChangeListeners.get(i).onBackStackChanged(); 2734cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2735cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2736cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2737cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2738cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn void addBackStackState(BackStackRecord state) { 2739cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStack == null) { 2740cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStack = new ArrayList<BackStackRecord>(); 2741cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2742cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStack.add(state); 2743cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2744dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2745d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy @SuppressWarnings("unused") 2746990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean popBackStackState(ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop, 2747990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount String name, int id, int flags) { 2748cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStack == null) { 2749cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return false; 2750cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2751990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (name == null && id < 0 && (flags & POP_BACK_STACK_INCLUSIVE) == 0) { 2752990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int last = mBackStack.size() - 1; 2753cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (last < 0) { 2754cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return false; 2755cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2756990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount records.add(mBackStack.remove(last)); 2757990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount isRecordPop.add(true); 2758cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 2759cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int index = -1; 2760cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (name != null || id >= 0) { 2761cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // If a name or ID is specified, look for that place in 2762cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // the stack. 2763cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn index = mBackStack.size()-1; 2764cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn while (index >= 0) { 2765cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn BackStackRecord bss = mBackStack.get(index); 2766cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (name != null && name.equals(bss.getName())) { 2767cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 2768cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2769cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (id >= 0 && id == bss.mIndex) { 2770cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 2771cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2772cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn index--; 2773cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2774cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (index < 0) { 2775cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return false; 2776cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2777cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if ((flags&POP_BACK_STACK_INCLUSIVE) != 0) { 2778cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn index--; 2779cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Consume all following entries that match. 2780cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn while (index >= 0) { 2781cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn BackStackRecord bss = mBackStack.get(index); 2782cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if ((name != null && name.equals(bss.getName())) 2783cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn || (id >= 0 && id == bss.mIndex)) { 2784cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn index--; 2785cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn continue; 2786cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2787cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 2788cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2789cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2790cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2791cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (index == mBackStack.size()-1) { 2792cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return false; 2793cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2794990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = mBackStack.size() - 1; i > index; i--) { 2795990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount records.add(mBackStack.remove(i)); 2796990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount isRecordPop.add(true); 2797cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2798cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2799cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return true; 2800cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2801dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2802c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell FragmentManagerNonConfig retainNonConfig() { 280325806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount setRetaining(mSavedNonConfig); 280425806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount return mSavedNonConfig; 280525806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount } 280625806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount 280725806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount /** 280825806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount * Recurse the FragmentManagerNonConfig fragments and set the mRetaining to true. This 280925806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount * was previously done while saving the non-config state, but that has been moved to 281025806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount * {@link #saveNonConfig()} called from {@link #saveAllState()}. If mRetaining is set too 281125806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount * early, the fragment won't be destroyed when the FragmentManager is destroyed. 281225806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount */ 281325806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount private static void setRetaining(FragmentManagerNonConfig nonConfig) { 281425806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount if (nonConfig == null) { 281525806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount return; 281625806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount } 281725806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount List<Fragment> fragments = nonConfig.getFragments(); 281825806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount if (fragments != null) { 281925806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount for (Fragment fragment : fragments) { 282025806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount fragment.mRetaining = true; 282125806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount } 282225806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount } 282325806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount List<FragmentManagerNonConfig> children = nonConfig.getChildNonConfigs(); 282425806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount if (children != null) { 282525806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount for (FragmentManagerNonConfig child : children) { 282625806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount setRetaining(child); 282725806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount } 282825806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount } 282925806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount } 283025806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount 283125806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount void saveNonConfig() { 2832cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ArrayList<Fragment> fragments = null; 2833c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell ArrayList<FragmentManagerNonConfig> childFragments = null; 283441516afc57ee5165d3a4e6c8a36f798d2cf6be4fIan Lake ArrayList<ViewModelStore> viewModelStores = null; 2835cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mActive != null) { 2836cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<mActive.size(); i++) { 283790b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount Fragment f = mActive.valueAt(i); 2838c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell if (f != null) { 2839c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell if (f.mRetainInstance) { 2840c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell if (fragments == null) { 2841c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell fragments = new ArrayList<Fragment>(); 2842c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell } 2843c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell fragments.add(f); 2844c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell f.mTargetIndex = f.mTarget != null ? f.mTarget.mIndex : -1; 2845c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell if (DEBUG) Log.v(TAG, "retainNonConfig: keeping retained " + f); 2846c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell } 2847d15baded7e3e904ef00ccda50449c2adf8374f11Sergey Vasilinets FragmentManagerNonConfig child; 2848c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell if (f.mChildFragmentManager != null) { 284925806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount f.mChildFragmentManager.saveNonConfig(); 2850d15baded7e3e904ef00ccda50449c2adf8374f11Sergey Vasilinets child = f.mChildFragmentManager.mSavedNonConfig; 2851d15baded7e3e904ef00ccda50449c2adf8374f11Sergey Vasilinets } else { 2852d15baded7e3e904ef00ccda50449c2adf8374f11Sergey Vasilinets // f.mChildNonConfig may be not null, when the parent fragment is 2853d15baded7e3e904ef00ccda50449c2adf8374f11Sergey Vasilinets // in the backstack. 2854d15baded7e3e904ef00ccda50449c2adf8374f11Sergey Vasilinets child = f.mChildNonConfig; 2855d15baded7e3e904ef00ccda50449c2adf8374f11Sergey Vasilinets } 2856d15baded7e3e904ef00ccda50449c2adf8374f11Sergey Vasilinets 2857d15baded7e3e904ef00ccda50449c2adf8374f11Sergey Vasilinets if (childFragments == null && child != null) { 2858d15baded7e3e904ef00ccda50449c2adf8374f11Sergey Vasilinets childFragments = new ArrayList<>(mActive.size()); 2859d15baded7e3e904ef00ccda50449c2adf8374f11Sergey Vasilinets for (int j = 0; j < i; j++) { 2860d15baded7e3e904ef00ccda50449c2adf8374f11Sergey Vasilinets childFragments.add(null); 2861c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell } 2862c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell } 2863d15baded7e3e904ef00ccda50449c2adf8374f11Sergey Vasilinets 2864d15baded7e3e904ef00ccda50449c2adf8374f11Sergey Vasilinets if (childFragments != null) { 2865d15baded7e3e904ef00ccda50449c2adf8374f11Sergey Vasilinets childFragments.add(child); 2866cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 286741516afc57ee5165d3a4e6c8a36f798d2cf6be4fIan Lake if (viewModelStores == null && f.mViewModelStore != null) { 286841516afc57ee5165d3a4e6c8a36f798d2cf6be4fIan Lake viewModelStores = new ArrayList<>(mActive.size()); 286941516afc57ee5165d3a4e6c8a36f798d2cf6be4fIan Lake for (int j = 0; j < i; j++) { 287041516afc57ee5165d3a4e6c8a36f798d2cf6be4fIan Lake viewModelStores.add(null); 287141516afc57ee5165d3a4e6c8a36f798d2cf6be4fIan Lake } 287241516afc57ee5165d3a4e6c8a36f798d2cf6be4fIan Lake } 287341516afc57ee5165d3a4e6c8a36f798d2cf6be4fIan Lake 287441516afc57ee5165d3a4e6c8a36f798d2cf6be4fIan Lake if (viewModelStores != null) { 287541516afc57ee5165d3a4e6c8a36f798d2cf6be4fIan Lake viewModelStores.add(f.mViewModelStore); 287641516afc57ee5165d3a4e6c8a36f798d2cf6be4fIan Lake } 2877cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2878cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2879cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 288041516afc57ee5165d3a4e6c8a36f798d2cf6be4fIan Lake if (fragments == null && childFragments == null && viewModelStores == null) { 288125806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount mSavedNonConfig = null; 288225806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount } else { 288341516afc57ee5165d3a4e6c8a36f798d2cf6be4fIan Lake mSavedNonConfig = new FragmentManagerNonConfig(fragments, childFragments, 288441516afc57ee5165d3a4e6c8a36f798d2cf6be4fIan Lake viewModelStores); 2885c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell } 2886cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2887dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2888cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn void saveFragmentViewState(Fragment f) { 2889cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mInnerView == null) { 2890cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return; 2891cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2892cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mStateArray == null) { 2893cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mStateArray = new SparseArray<Parcelable>(); 2894ea2c91b0198855073983b4a8437aa71cbd83872fDianne Hackborn } else { 2895ea2c91b0198855073983b4a8437aa71cbd83872fDianne Hackborn mStateArray.clear(); 2896cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2897cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mInnerView.saveHierarchyState(mStateArray); 2898cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mStateArray.size() > 0) { 2899cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mSavedViewState = mStateArray; 2900cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mStateArray = null; 2901cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2902cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2903dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 29045c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn Bundle saveFragmentBasicState(Fragment f) { 29055c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn Bundle result = null; 29065c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn 29075c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn if (mStateBundle == null) { 29085c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn mStateBundle = new Bundle(); 29095c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 29100adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn f.performSaveInstanceState(mStateBundle); 2911267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell dispatchOnFragmentSaveInstanceState(f, mStateBundle, false); 29125c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn if (!mStateBundle.isEmpty()) { 29135c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn result = mStateBundle; 29145c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn mStateBundle = null; 29155c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 29165c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn 29175c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn if (f.mView != null) { 29185c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn saveFragmentViewState(f); 29195c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 29205c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn if (f.mSavedViewState != null) { 29215c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn if (result == null) { 29225c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn result = new Bundle(); 29235c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 29245c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn result.putSparseParcelableArray( 29255c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn FragmentManagerImpl.VIEW_STATE_TAG, f.mSavedViewState); 29265c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 292779398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell if (!f.mUserVisibleHint) { 2928f4c0cf637ba73374a206cec26c09d4dfa4c1a364Jake Wharton if (result == null) { 2929f4c0cf637ba73374a206cec26c09d4dfa4c1a364Jake Wharton result = new Bundle(); 2930f4c0cf637ba73374a206cec26c09d4dfa4c1a364Jake Wharton } 293179398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell // Only add this if it's not the default value 293279398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell result.putBoolean(FragmentManagerImpl.USER_VISIBLE_HINT_TAG, f.mUserVisibleHint); 293379398eaefea45e61d839cf4e0534f0eafee70a09Adam Powell } 29345c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn 29355c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn return result; 29365c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn } 29375c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn 2938cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Parcelable saveAllState() { 2939cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Make sure all pending operations have now been executed to get 2940cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // our state update-to-date. 2941990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount forcePostponedTransactions(); 2942990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount endAnimatingAwayFragments(); 2943cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn execPendingActions(); 2944cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 29459d359be2fec790cf02c3201c89ff37d425d35058Aurimas Liutikas mStateSaved = true; 294625806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount mSavedNonConfig = null; 2947cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2948cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mActive == null || mActive.size() <= 0) { 2949cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 2950cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2951dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2952cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // First collect all active fragments. 2953cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int N = mActive.size(); 2954cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentState[] active = new FragmentState[N]; 2955cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn boolean haveFragments = false; 2956cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<N; i++) { 295790b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount Fragment f = mActive.valueAt(i); 2958cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f != null) { 29591b913519b1c03b084779851e81db2e1a11eb0b0dDianne Hackborn if (f.mIndex < 0) { 296013fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn throwException(new IllegalStateException( 296113fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn "Failure saving state: active " + f 296213fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn + " has cleared index: " + f.mIndex)); 29631b913519b1c03b084779851e81db2e1a11eb0b0dDianne Hackborn } 29641b913519b1c03b084779851e81db2e1a11eb0b0dDianne Hackborn 2965cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn haveFragments = true; 2966dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2967cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentState fs = new FragmentState(f); 2968cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn active[i] = fs; 2969dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2970cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mState > Fragment.INITIALIZING && fs.mSavedFragmentState == null) { 29715c1637087453de15e31861f073eae5133c4e9f7bDianne Hackborn fs.mSavedFragmentState = saveFragmentBasicState(f); 2972cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2973cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mTarget != null) { 2974cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mTarget.mIndex < 0) { 297513fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn throwException(new IllegalStateException( 297613fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn "Failure saving state: " + f 297713fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn + " has target not in fragment manager: " + f.mTarget)); 2978cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2979cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (fs.mSavedFragmentState == null) { 2980cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fs.mSavedFragmentState = new Bundle(); 2981cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2982cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn putFragment(fs.mSavedFragmentState, 2983cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentManagerImpl.TARGET_STATE_TAG, f.mTarget); 2984cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f.mTargetRequestCode != 0) { 2985cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fs.mSavedFragmentState.putInt( 2986cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 2987cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mTargetRequestCode); 2988cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2989cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2990cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 2991cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 2992cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fs.mSavedFragmentState = f.mSavedFragmentState; 2993cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2994dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 2995cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "Saved state of " + f + ": " 2996cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn + fs.mSavedFragmentState); 2997cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2998cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 2999dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3000cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (!haveFragments) { 3001cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "saveAllState: no fragments!"); 3002cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return null; 3003cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3004dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3005cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int[] added = null; 3006cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn BackStackState[] backStack = null; 3007dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3008cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Build list of currently added fragments. 3009ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount N = mAdded.size(); 3010ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount if (N > 0) { 3011ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount added = new int[N]; 3012ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount for (int i = 0; i < N; i++) { 3013ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount added[i] = mAdded.get(i).mIndex; 3014ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount if (added[i] < 0) { 3015ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount throwException(new IllegalStateException( 3016ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount "Failure saving state: active " + mAdded.get(i) 3017ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount + " has cleared index: " + added[i])); 3018ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount } 3019ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount if (DEBUG) { 3020ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount Log.v(TAG, "saveAllState: adding fragment #" + i 3021cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn + ": " + mAdded.get(i)); 3022cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3023cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3024cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3025dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3026cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Now save back stack. 3027cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mBackStack != null) { 3028cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn N = mBackStack.size(); 3029cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (N > 0) { 3030cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn backStack = new BackStackState[N]; 3031cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<N; i++) { 3032d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy backStack[i] = new BackStackState(mBackStack.get(i)); 3033cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "saveAllState: adding back stack #" + i 3034cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn + ": " + mBackStack.get(i)); 3035cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3036cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3037cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3038dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3039cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentManagerState fms = new FragmentManagerState(); 3040cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fms.mActive = active; 3041cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fms.mAdded = added; 3042cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fms.mBackStack = backStack; 3043418738949305a8a0e30eba92c125c650048f9c50Adam Powell if (mPrimaryNav != null) { 3044418738949305a8a0e30eba92c125c650048f9c50Adam Powell fms.mPrimaryNavActiveIndex = mPrimaryNav.mIndex; 3045418738949305a8a0e30eba92c125c650048f9c50Adam Powell } 304690b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount fms.mNextFragmentIndex = mNextFragmentIndex; 304725806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount saveNonConfig(); 3048cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return fms; 3049cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3050dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3051c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell void restoreAllState(Parcelable state, FragmentManagerNonConfig nonConfig) { 3052cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // If there is no saved state at all, then there can not be 3053cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // any nonConfig fragments either, so that is that. 3054cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (state == null) return; 3055cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentManagerState fms = (FragmentManagerState)state; 3056cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (fms.mActive == null) return; 3057c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell 3058c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell List<FragmentManagerNonConfig> childNonConfigs = null; 305941516afc57ee5165d3a4e6c8a36f798d2cf6be4fIan Lake List<ViewModelStore> viewModelStores = null; 3060c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell 3061cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // First re-attach any non-config instances we are retaining back 3062cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // to their saved state, so we don't try to instantiate them again. 3063cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (nonConfig != null) { 3064c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell List<Fragment> nonConfigFragments = nonConfig.getFragments(); 3065c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell childNonConfigs = nonConfig.getChildNonConfigs(); 306641516afc57ee5165d3a4e6c8a36f798d2cf6be4fIan Lake viewModelStores = nonConfig.getViewModelStores(); 3067c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell final int count = nonConfigFragments != null ? nonConfigFragments.size() : 0; 3068c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell for (int i = 0; i < count; i++) { 3069c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell Fragment f = nonConfigFragments.get(i); 3070cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (DEBUG) Log.v(TAG, "restoreAllState: re-attaching retained " + f); 307138083235ff15c516dbba4ef655f4895b0282cf7bGeorge Mount int index = 0; // index into fms.mActive 307238083235ff15c516dbba4ef655f4895b0282cf7bGeorge Mount while (index < fms.mActive.length && fms.mActive[index].mIndex != f.mIndex) { 307338083235ff15c516dbba4ef655f4895b0282cf7bGeorge Mount index++; 307438083235ff15c516dbba4ef655f4895b0282cf7bGeorge Mount } 307538083235ff15c516dbba4ef655f4895b0282cf7bGeorge Mount if (index == fms.mActive.length) { 307638083235ff15c516dbba4ef655f4895b0282cf7bGeorge Mount throwException(new IllegalStateException("Could not find active fragment " 307738083235ff15c516dbba4ef655f4895b0282cf7bGeorge Mount + "with index " + f.mIndex)); 307838083235ff15c516dbba4ef655f4895b0282cf7bGeorge Mount } 307938083235ff15c516dbba4ef655f4895b0282cf7bGeorge Mount FragmentState fs = fms.mActive[index]; 3080cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fs.mInstance = f; 3081cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mSavedViewState = null; 3082cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mBackStackNesting = 0; 3083cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mInLayout = false; 3084cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mAdded = false; 30852c4b5dbfee5232bcbbcb74b84ce9147b62a9d789Dianne Hackborn f.mTarget = null; 3086cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (fs.mSavedFragmentState != null) { 3087d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy fs.mSavedFragmentState.setClassLoader(mHost.getContext().getClassLoader()); 3088cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mSavedViewState = fs.mSavedFragmentState.getSparseParcelableArray( 3089cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentManagerImpl.VIEW_STATE_TAG); 30908e4a59b54e9225b77151805dd6b8867dcd8e60a4Craig Mautner f.mSavedFragmentState = fs.mSavedFragmentState; 3091cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3092cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3093cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3094dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3095cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Build the full list of active fragments, instantiating them from 3096cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // their saved state. 309790b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount mActive = new SparseArray<>(fms.mActive.length); 3098cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<fms.mActive.length; i++) { 3099cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn FragmentState fs = fms.mActive[i]; 3100cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (fs != null) { 3101c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell FragmentManagerNonConfig childNonConfig = null; 3102c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell if (childNonConfigs != null && i < childNonConfigs.size()) { 3103c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell childNonConfig = childNonConfigs.get(i); 3104c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell } 310541516afc57ee5165d3a4e6c8a36f798d2cf6be4fIan Lake ViewModelStore viewModelStore = null; 310641516afc57ee5165d3a4e6c8a36f798d2cf6be4fIan Lake if (viewModelStores != null && i < viewModelStores.size()) { 310741516afc57ee5165d3a4e6c8a36f798d2cf6be4fIan Lake viewModelStore = viewModelStores.get(i); 310841516afc57ee5165d3a4e6c8a36f798d2cf6be4fIan Lake } 310941516afc57ee5165d3a4e6c8a36f798d2cf6be4fIan Lake Fragment f = fs.instantiate(mHost, mContainer, mParent, childNonConfig, 311041516afc57ee5165d3a4e6c8a36f798d2cf6be4fIan Lake viewModelStore); 31113a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn if (DEBUG) Log.v(TAG, "restoreAllState: active #" + i + ": " + f); 311290b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount mActive.put(f.mIndex, f); 3113cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Now that the fragment is instantiated (or came from being 3114cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // retained above), clear mInstance in case we end up re-restoring 3115cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // from this FragmentState again. 3116cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn fs.mInstance = null; 3117cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3118cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3119dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3120cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Update the target of all retained fragments. 3121cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (nonConfig != null) { 3122c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell List<Fragment> nonConfigFragments = nonConfig.getFragments(); 3123c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell final int count = nonConfigFragments != null ? nonConfigFragments.size() : 0; 3124c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell for (int i = 0; i < count; i++) { 3125c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell Fragment f = nonConfigFragments.get(i); 31262c4b5dbfee5232bcbbcb74b84ce9147b62a9d789Dianne Hackborn if (f.mTargetIndex >= 0) { 312790b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount f.mTarget = mActive.get(f.mTargetIndex); 312890b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount if (f.mTarget == null) { 3129cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Log.w(TAG, "Re-attaching retained fragment " + f 31302c4b5dbfee5232bcbbcb74b84ce9147b62a9d789Dianne Hackborn + " target no longer exists: " + f.mTargetIndex); 3131cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3132cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3133cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3134cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3135cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 3136cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Build the list of currently added fragments. 3137ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount mAdded.clear(); 3138cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (fms.mAdded != null) { 3139cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<fms.mAdded.length; i++) { 3140cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mActive.get(fms.mAdded[i]); 3141cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (f == null) { 314213fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn throwException(new IllegalStateException( 314313fb2b96fa8464e7b8514c57e1ad5ea782b3a52cDianne Hackborn "No instantiated fragment for index #" + fms.mAdded[i])); 3144cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3145cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.mAdded = true; 31463a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn if (DEBUG) Log.v(TAG, "restoreAllState: added #" + i + ": " + f); 31473a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn if (mAdded.contains(f)) { 31483a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn throw new IllegalStateException("Already added!"); 31493a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn } 315096221034e4a23a2abb83f772a0281bb197ac5ac0George Mount synchronized (mAdded) { 315196221034e4a23a2abb83f772a0281bb197ac5ac0George Mount mAdded.add(f); 315296221034e4a23a2abb83f772a0281bb197ac5ac0George Mount } 3153cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3154cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3155dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3156cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn // Build the back stack. 3157cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (fms.mBackStack != null) { 3158cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStack = new ArrayList<BackStackRecord>(fms.mBackStack.length); 3159cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<fms.mBackStack.length; i++) { 3160cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn BackStackRecord bse = fms.mBackStack[i].instantiate(this); 31613a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn if (DEBUG) { 31623a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn Log.v(TAG, "restoreAllState: back stack #" + i 3163cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn + " (index " + bse.mIndex + "): " + bse); 31643a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn LogWriter logw = new LogWriter(TAG); 31653a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn PrintWriter pw = new PrintWriter(logw); 31663a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn bse.dump(" ", pw, false); 3167f83358389f0c4ea37a7e7d9e493857f99baf0440Chris Banes pw.close(); 31683a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn } 3169cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStack.add(bse); 3170cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (bse.mIndex >= 0) { 3171cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn setBackStackIndex(bse.mIndex, bse); 3172cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3173cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3174cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } else { 3175cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mBackStack = null; 3176cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3177418738949305a8a0e30eba92c125c650048f9c50Adam Powell 3178418738949305a8a0e30eba92c125c650048f9c50Adam Powell if (fms.mPrimaryNavActiveIndex >= 0) { 3179418738949305a8a0e30eba92c125c650048f9c50Adam Powell mPrimaryNav = mActive.get(fms.mPrimaryNavActiveIndex); 3180418738949305a8a0e30eba92c125c650048f9c50Adam Powell } 318190b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount this.mNextFragmentIndex = fms.mNextFragmentIndex; 318290b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount } 318390b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount 318490b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount /** 318590b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount * To prevent list modification errors, mActive sets values to null instead of 318690b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount * removing them when the Fragment becomes inactive. This cleans up the list at the 318790b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount * end of executing the transactions. 318890b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount */ 318990b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount private void burpActive() { 319090b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount if (mActive != null) { 319190b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount for (int i = mActive.size() - 1; i >= 0; i--) { 319290b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount if (mActive.valueAt(i) == null) { 319390b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount mActive.delete(mActive.keyAt(i)); 319490b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount } 319590b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount } 319690b15311c0461be519432794b7f8e8132fb7a72cGeorge Mount } 3197cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3198d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy 31998491eb62f621cd5de4b4caed839be09c77011f53Todd Kennedy public void attachController(FragmentHostCallback host, 32000adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn FragmentContainer container, Fragment parent) { 3201d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy if (mHost != null) throw new IllegalStateException("Already attached"); 3202d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy mHost = host; 32030adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn mContainer = container; 32040adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn mParent = parent; 3205cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3206dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3207cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void noteStateNotSaved() { 320825806414c27ad7a9b194e01328b1315058d3d2adGeorge Mount mSavedNonConfig = null; 3209cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mStateSaved = false; 32100d429d5f5bb0d6197d5c7a24b5c0bb5bcd5db8cdIan Lake mStopped = false; 3211ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount final int addedCount = mAdded.size(); 32120765353c002bfdf681c982565810aa4be3499dd0George Mount for (int i = 0; i < addedCount; i++) { 32130765353c002bfdf681c982565810aa4be3499dd0George Mount Fragment fragment = mAdded.get(i); 32140765353c002bfdf681c982565810aa4be3499dd0George Mount if (fragment != null) { 32150765353c002bfdf681c982565810aa4be3499dd0George Mount fragment.noteStateNotSaved(); 32160765353c002bfdf681c982565810aa4be3499dd0George Mount } 32170765353c002bfdf681c982565810aa4be3499dd0George Mount } 3218cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3219dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3220cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchCreate() { 3221cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mStateSaved = false; 32220d429d5f5bb0d6197d5c7a24b5c0bb5bcd5db8cdIan Lake mStopped = false; 3223aee2fb02851620a16703f950f865d990fc64cf6dGeorge Mount dispatchStateChange(Fragment.CREATED); 3224cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3225dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3226cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchActivityCreated() { 3227cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mStateSaved = false; 32280d429d5f5bb0d6197d5c7a24b5c0bb5bcd5db8cdIan Lake mStopped = false; 3229aee2fb02851620a16703f950f865d990fc64cf6dGeorge Mount dispatchStateChange(Fragment.ACTIVITY_CREATED); 3230cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3231dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3232cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchStart() { 3233cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mStateSaved = false; 32340d429d5f5bb0d6197d5c7a24b5c0bb5bcd5db8cdIan Lake mStopped = false; 3235aee2fb02851620a16703f950f865d990fc64cf6dGeorge Mount dispatchStateChange(Fragment.STARTED); 3236cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3237dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3238cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchResume() { 3239cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mStateSaved = false; 32400d429d5f5bb0d6197d5c7a24b5c0bb5bcd5db8cdIan Lake mStopped = false; 3241aee2fb02851620a16703f950f865d990fc64cf6dGeorge Mount dispatchStateChange(Fragment.RESUMED); 3242cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3243dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3244cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchPause() { 3245aee2fb02851620a16703f950f865d990fc64cf6dGeorge Mount dispatchStateChange(Fragment.STARTED); 3246cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3247dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3248cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchStop() { 32490d429d5f5bb0d6197d5c7a24b5c0bb5bcd5db8cdIan Lake mStopped = true; 3250aee2fb02851620a16703f950f865d990fc64cf6dGeorge Mount dispatchStateChange(Fragment.STOPPED); 3251cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3252dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3253218c1e661578e2a17928f7dbb590b43d1c79aeb7Dianne Hackborn public void dispatchReallyStop() { 3254aee2fb02851620a16703f950f865d990fc64cf6dGeorge Mount dispatchStateChange(Fragment.ACTIVITY_CREATED); 3255681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn } 3256681a6fb06bdedb8661a68a1b9e34727b6059aa39Dianne Hackborn 32570adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn public void dispatchDestroyView() { 3258aee2fb02851620a16703f950f865d990fc64cf6dGeorge Mount dispatchStateChange(Fragment.CREATED); 32590adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn } 32600adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn 3261cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchDestroy() { 3262cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mDestroyed = true; 3263e8b402b00c0cbdac050c349a5fc89c34580f3185Dianne Hackborn execPendingActions(); 3264aee2fb02851620a16703f950f865d990fc64cf6dGeorge Mount dispatchStateChange(Fragment.INITIALIZING); 3265d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy mHost = null; 32660adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn mContainer = null; 32670adacc1aa313d757ae1c517152cef838e0f35c13Dianne Hackborn mParent = null; 3268cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 32695fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian 3270aee2fb02851620a16703f950f865d990fc64cf6dGeorge Mount private void dispatchStateChange(int nextState) { 3271aee2fb02851620a16703f950f865d990fc64cf6dGeorge Mount try { 3272aee2fb02851620a16703f950f865d990fc64cf6dGeorge Mount mExecutingActions = true; 3273aee2fb02851620a16703f950f865d990fc64cf6dGeorge Mount moveToState(nextState, false); 3274aee2fb02851620a16703f950f865d990fc64cf6dGeorge Mount } finally { 3275aee2fb02851620a16703f950f865d990fc64cf6dGeorge Mount mExecutingActions = false; 3276aee2fb02851620a16703f950f865d990fc64cf6dGeorge Mount } 3277aee2fb02851620a16703f950f865d990fc64cf6dGeorge Mount execPendingActions(); 3278aee2fb02851620a16703f950f865d990fc64cf6dGeorge Mount } 3279aee2fb02851620a16703f950f865d990fc64cf6dGeorge Mount 32805fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian public void dispatchMultiWindowModeChanged(boolean isInMultiWindowMode) { 32815fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian for (int i = mAdded.size() - 1; i >= 0; --i) { 3282ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas final Fragment f = mAdded.get(i); 32835fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian if (f != null) { 32845fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian f.performMultiWindowModeChanged(isInMultiWindowMode); 32855fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian } 32865fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian } 32875fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian } 32885fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian 32895fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian public void dispatchPictureInPictureModeChanged(boolean isInPictureInPictureMode) { 32905fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian for (int i = mAdded.size() - 1; i >= 0; --i) { 3291ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas final Fragment f = mAdded.get(i); 32925fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian if (f != null) { 32935fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian f.performPictureInPictureModeChanged(isInPictureInPictureMode); 32945fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian } 32955fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian } 32965fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian } 32975fa6d3dd3f408ceb2ff7368fd0259713d9382ad8Andrii Kulian 3298cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchConfigurationChanged(Configuration newConfig) { 3299ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount for (int i = 0; i < mAdded.size(); i++) { 3300ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount Fragment f = mAdded.get(i); 3301ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount if (f != null) { 3302ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount f.performConfigurationChanged(newConfig); 3303cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3304cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3305cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3306cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 3307cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchLowMemory() { 3308ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount for (int i = 0; i < mAdded.size(); i++) { 3309ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount Fragment f = mAdded.get(i); 3310ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount if (f != null) { 3311ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount f.performLowMemory(); 3312cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3313cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3314cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3315cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn 3316cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean dispatchCreateOptionsMenu(Menu menu, MenuInflater inflater) { 33175b9fbc316b9c49c57ffbdcdcef1ee83171fd189aGeorge Mount if (mCurState < Fragment.CREATED) { 33185b9fbc316b9c49c57ffbdcdcef1ee83171fd189aGeorge Mount return false; 33195b9fbc316b9c49c57ffbdcdcef1ee83171fd189aGeorge Mount } 3320cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn boolean show = false; 3321cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn ArrayList<Fragment> newMenus = null; 3322ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount for (int i = 0; i < mAdded.size(); i++) { 3323ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount Fragment f = mAdded.get(i); 3324ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount if (f != null) { 3325ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount if (f.performCreateOptionsMenu(menu, inflater)) { 3326ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount show = true; 3327ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount if (newMenus == null) { 3328ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount newMenus = new ArrayList<Fragment>(); 3329cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3330ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount newMenus.add(f); 3331cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3332cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3333cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3334c1e87ac17c772ee3c5fd3b3f08321226e2c7ffa4Chris Banes 3335cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (mCreatedMenus != null) { 3336cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn for (int i=0; i<mCreatedMenus.size(); i++) { 3337cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn Fragment f = mCreatedMenus.get(i); 3338cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn if (newMenus == null || !newMenus.contains(f)) { 3339cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn f.onDestroyOptionsMenu(); 3340cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3341cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3342cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3343c1e87ac17c772ee3c5fd3b3f08321226e2c7ffa4Chris Banes 3344cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn mCreatedMenus = newMenus; 3345c1e87ac17c772ee3c5fd3b3f08321226e2c7ffa4Chris Banes 3346cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return show; 3347cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3348dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3349cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean dispatchPrepareOptionsMenu(Menu menu) { 33505b9fbc316b9c49c57ffbdcdcef1ee83171fd189aGeorge Mount if (mCurState < Fragment.CREATED) { 33515b9fbc316b9c49c57ffbdcdcef1ee83171fd189aGeorge Mount return false; 33525b9fbc316b9c49c57ffbdcdcef1ee83171fd189aGeorge Mount } 3353cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn boolean show = false; 3354ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount for (int i = 0; i < mAdded.size(); i++) { 3355ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount Fragment f = mAdded.get(i); 3356ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount if (f != null) { 3357ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount if (f.performPrepareOptionsMenu(menu)) { 3358ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount show = true; 3359cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3360cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3361cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3362cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return show; 3363cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3364dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3365cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean dispatchOptionsItemSelected(MenuItem item) { 33665b9fbc316b9c49c57ffbdcdcef1ee83171fd189aGeorge Mount if (mCurState < Fragment.CREATED) { 33675b9fbc316b9c49c57ffbdcdcef1ee83171fd189aGeorge Mount return false; 33685b9fbc316b9c49c57ffbdcdcef1ee83171fd189aGeorge Mount } 3369ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount for (int i = 0; i < mAdded.size(); i++) { 3370ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount Fragment f = mAdded.get(i); 3371ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount if (f != null) { 3372ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount if (f.performOptionsItemSelected(item)) { 3373ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount return true; 3374cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3375cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3376cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3377cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return false; 3378cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3379dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3380cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public boolean dispatchContextItemSelected(MenuItem item) { 33815b9fbc316b9c49c57ffbdcdcef1ee83171fd189aGeorge Mount if (mCurState < Fragment.CREATED) { 33825b9fbc316b9c49c57ffbdcdcef1ee83171fd189aGeorge Mount return false; 33835b9fbc316b9c49c57ffbdcdcef1ee83171fd189aGeorge Mount } 3384ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount for (int i = 0; i < mAdded.size(); i++) { 3385ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount Fragment f = mAdded.get(i); 3386ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount if (f != null) { 3387ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount if (f.performContextItemSelected(item)) { 3388ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount return true; 3389cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3390cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3391cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3392cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return false; 3393cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3394dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3395cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public void dispatchOptionsMenuClosed(Menu menu) { 33965b9fbc316b9c49c57ffbdcdcef1ee83171fd189aGeorge Mount if (mCurState < Fragment.CREATED) { 33975b9fbc316b9c49c57ffbdcdcef1ee83171fd189aGeorge Mount return; 33985b9fbc316b9c49c57ffbdcdcef1ee83171fd189aGeorge Mount } 3399ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount for (int i = 0; i < mAdded.size(); i++) { 3400ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount Fragment f = mAdded.get(i); 3401ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount if (f != null) { 3402ca32d4043899ec48d5807f24c2f1a513c8b3824eGeorge Mount f.performOptionsMenuClosed(menu); 3403cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3404cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3405cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3406461b48b4588ac21b97aa40553f04222c2c0344e7Chris Banes 3407b7a2c474fc66d5b7f2a57f2c212f8ac5a9e6de70Aurimas Liutikas @SuppressWarnings("ReferenceEquality") 3408418738949305a8a0e30eba92c125c650048f9c50Adam Powell public void setPrimaryNavigationFragment(Fragment f) { 340996767975440de77e44a231e6ef66b374b1403bd0George Mount if (f != null && (mActive.get(f.mIndex) != f 341096767975440de77e44a231e6ef66b374b1403bd0George Mount || (f.mHost != null && f.getFragmentManager() != this))) { 3411418738949305a8a0e30eba92c125c650048f9c50Adam Powell throw new IllegalArgumentException("Fragment " + f 3412418738949305a8a0e30eba92c125c650048f9c50Adam Powell + " is not an active fragment of FragmentManager " + this); 3413418738949305a8a0e30eba92c125c650048f9c50Adam Powell } 3414418738949305a8a0e30eba92c125c650048f9c50Adam Powell mPrimaryNav = f; 3415418738949305a8a0e30eba92c125c650048f9c50Adam Powell } 3416418738949305a8a0e30eba92c125c650048f9c50Adam Powell 3417e2104f4b5c8e3ad63570306a25e61502dfe4c418Aurimas Liutikas @Override 3418380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @Nullable 3419418738949305a8a0e30eba92c125c650048f9c50Adam Powell public Fragment getPrimaryNavigationFragment() { 3420418738949305a8a0e30eba92c125c650048f9c50Adam Powell return mPrimaryNav; 3421418738949305a8a0e30eba92c125c650048f9c50Adam Powell } 3422418738949305a8a0e30eba92c125c650048f9c50Adam Powell 3423e2104f4b5c8e3ad63570306a25e61502dfe4c418Aurimas Liutikas @Override 3424267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell public void registerFragmentLifecycleCallbacks(FragmentLifecycleCallbacks cb, 3425267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell boolean recursive) { 3426805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton mLifecycleCallbacks.add(new FragmentLifecycleCallbacksHolder(cb, recursive)); 3427267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3428267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3429e2104f4b5c8e3ad63570306a25e61502dfe4c418Aurimas Liutikas @Override 3430267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell public void unregisterFragmentLifecycleCallbacks(FragmentLifecycleCallbacks cb) { 3431267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell synchronized (mLifecycleCallbacks) { 3432267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell for (int i = 0, N = mLifecycleCallbacks.size(); i < N; i++) { 3433805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton if (mLifecycleCallbacks.get(i).mCallback == cb) { 3434267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell mLifecycleCallbacks.remove(i); 3435267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell break; 3436267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3437267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3438267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3439267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3440267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3441380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton void dispatchOnFragmentPreAttached(@NonNull Fragment f, @NonNull Context context, 3442380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton boolean onlyRecursive) { 3443267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mParent != null) { 3444267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell FragmentManager parentManager = mParent.getFragmentManager(); 3445267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (parentManager instanceof FragmentManagerImpl) { 3446267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell ((FragmentManagerImpl) parentManager) 3447267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell .dispatchOnFragmentPreAttached(f, context, true); 3448267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3449267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3450805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton for (FragmentLifecycleCallbacksHolder holder : mLifecycleCallbacks) { 3451805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton if (!onlyRecursive || holder.mRecursive) { 3452805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton holder.mCallback.onFragmentPreAttached(this, f, context); 3453267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3454267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3455267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3456267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3457380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton void dispatchOnFragmentAttached(@NonNull Fragment f, @NonNull Context context, 3458380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton boolean onlyRecursive) { 3459267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mParent != null) { 3460267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell FragmentManager parentManager = mParent.getFragmentManager(); 3461267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (parentManager instanceof FragmentManagerImpl) { 3462267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell ((FragmentManagerImpl) parentManager) 3463267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell .dispatchOnFragmentAttached(f, context, true); 3464267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3465267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3466805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton for (FragmentLifecycleCallbacksHolder holder : mLifecycleCallbacks) { 3467805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton if (!onlyRecursive || holder.mRecursive) { 3468805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton holder.mCallback.onFragmentAttached(this, f, context); 3469267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3470267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3471267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3472267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3473380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton void dispatchOnFragmentPreCreated(@NonNull Fragment f, @Nullable Bundle savedInstanceState, 34741d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell boolean onlyRecursive) { 34751d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell if (mParent != null) { 34761d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell FragmentManager parentManager = mParent.getFragmentManager(); 34771d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell if (parentManager instanceof FragmentManagerImpl) { 34781d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell ((FragmentManagerImpl) parentManager) 34791d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell .dispatchOnFragmentPreCreated(f, savedInstanceState, true); 34801d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell } 34811d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell } 3482805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton for (FragmentLifecycleCallbacksHolder holder : mLifecycleCallbacks) { 3483805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton if (!onlyRecursive || holder.mRecursive) { 3484805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton holder.mCallback.onFragmentPreCreated(this, f, savedInstanceState); 34851d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell } 34861d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell } 34871d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell } 34881d1dad664f27bc66fa52e4b0a294a5efb5af0ea1Adam Powell 3489380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton void dispatchOnFragmentCreated(@NonNull Fragment f, @Nullable Bundle savedInstanceState, 3490380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton boolean onlyRecursive) { 3491267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mParent != null) { 3492267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell FragmentManager parentManager = mParent.getFragmentManager(); 3493267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (parentManager instanceof FragmentManagerImpl) { 3494267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell ((FragmentManagerImpl) parentManager) 3495267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell .dispatchOnFragmentCreated(f, savedInstanceState, true); 3496267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3497267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3498805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton for (FragmentLifecycleCallbacksHolder holder : mLifecycleCallbacks) { 3499805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton if (!onlyRecursive || holder.mRecursive) { 3500805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton holder.mCallback.onFragmentCreated(this, f, savedInstanceState); 3501267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3502267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3503267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3504267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3505380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton void dispatchOnFragmentActivityCreated(@NonNull Fragment f, @Nullable Bundle savedInstanceState, 3506267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell boolean onlyRecursive) { 3507267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mParent != null) { 3508267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell FragmentManager parentManager = mParent.getFragmentManager(); 3509267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (parentManager instanceof FragmentManagerImpl) { 3510267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell ((FragmentManagerImpl) parentManager) 3511267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell .dispatchOnFragmentActivityCreated(f, savedInstanceState, true); 3512267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3513267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3514805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton for (FragmentLifecycleCallbacksHolder holder : mLifecycleCallbacks) { 3515805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton if (!onlyRecursive || holder.mRecursive) { 3516805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton holder.mCallback.onFragmentActivityCreated(this, f, savedInstanceState); 3517267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3518267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3519267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3520267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3521380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton void dispatchOnFragmentViewCreated(@NonNull Fragment f, @NonNull View v, 3522380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton @Nullable Bundle savedInstanceState, boolean onlyRecursive) { 3523267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mParent != null) { 3524267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell FragmentManager parentManager = mParent.getFragmentManager(); 3525267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (parentManager instanceof FragmentManagerImpl) { 3526267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell ((FragmentManagerImpl) parentManager) 3527267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell .dispatchOnFragmentViewCreated(f, v, savedInstanceState, true); 3528267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3529267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3530805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton for (FragmentLifecycleCallbacksHolder holder : mLifecycleCallbacks) { 3531805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton if (!onlyRecursive || holder.mRecursive) { 3532805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton holder.mCallback.onFragmentViewCreated(this, f, v, savedInstanceState); 3533267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3534267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3535267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3536267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3537380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton void dispatchOnFragmentStarted(@NonNull Fragment f, boolean onlyRecursive) { 3538267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mParent != null) { 3539267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell FragmentManager parentManager = mParent.getFragmentManager(); 3540267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (parentManager instanceof FragmentManagerImpl) { 3541267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell ((FragmentManagerImpl) parentManager) 3542267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell .dispatchOnFragmentStarted(f, true); 3543267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3544267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3545805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton for (FragmentLifecycleCallbacksHolder holder : mLifecycleCallbacks) { 3546805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton if (!onlyRecursive || holder.mRecursive) { 3547805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton holder.mCallback.onFragmentStarted(this, f); 3548267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3549267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3550267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3551267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3552380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton void dispatchOnFragmentResumed(@NonNull Fragment f, boolean onlyRecursive) { 3553267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mParent != null) { 3554267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell FragmentManager parentManager = mParent.getFragmentManager(); 3555267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (parentManager instanceof FragmentManagerImpl) { 3556267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell ((FragmentManagerImpl) parentManager) 3557267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell .dispatchOnFragmentResumed(f, true); 3558267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3559267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3560805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton for (FragmentLifecycleCallbacksHolder holder : mLifecycleCallbacks) { 3561805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton if (!onlyRecursive || holder.mRecursive) { 3562805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton holder.mCallback.onFragmentResumed(this, f); 3563267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3564267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3565267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3566267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3567380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton void dispatchOnFragmentPaused(@NonNull Fragment f, boolean onlyRecursive) { 3568267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mParent != null) { 3569267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell FragmentManager parentManager = mParent.getFragmentManager(); 3570267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (parentManager instanceof FragmentManagerImpl) { 3571267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell ((FragmentManagerImpl) parentManager) 3572267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell .dispatchOnFragmentPaused(f, true); 3573267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3574267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3575805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton for (FragmentLifecycleCallbacksHolder holder : mLifecycleCallbacks) { 3576805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton if (!onlyRecursive || holder.mRecursive) { 3577805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton holder.mCallback.onFragmentPaused(this, f); 3578267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3579267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3580267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3581267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3582380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton void dispatchOnFragmentStopped(@NonNull Fragment f, boolean onlyRecursive) { 3583267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mParent != null) { 3584267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell FragmentManager parentManager = mParent.getFragmentManager(); 3585267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (parentManager instanceof FragmentManagerImpl) { 3586267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell ((FragmentManagerImpl) parentManager) 3587267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell .dispatchOnFragmentStopped(f, true); 3588267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3589267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3590805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton for (FragmentLifecycleCallbacksHolder holder : mLifecycleCallbacks) { 3591805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton if (!onlyRecursive || holder.mRecursive) { 3592805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton holder.mCallback.onFragmentStopped(this, f); 3593267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3594267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3595267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3596267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3597380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton void dispatchOnFragmentSaveInstanceState(@NonNull Fragment f, @NonNull Bundle outState, 3598380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton boolean onlyRecursive) { 3599267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mParent != null) { 3600267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell FragmentManager parentManager = mParent.getFragmentManager(); 3601267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (parentManager instanceof FragmentManagerImpl) { 3602267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell ((FragmentManagerImpl) parentManager) 3603267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell .dispatchOnFragmentSaveInstanceState(f, outState, true); 3604267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3605267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3606805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton for (FragmentLifecycleCallbacksHolder holder : mLifecycleCallbacks) { 3607805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton if (!onlyRecursive || holder.mRecursive) { 3608805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton holder.mCallback.onFragmentSaveInstanceState(this, f, outState); 3609267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3610267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3611267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3612267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3613380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton void dispatchOnFragmentViewDestroyed(@NonNull Fragment f, boolean onlyRecursive) { 3614267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mParent != null) { 3615267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell FragmentManager parentManager = mParent.getFragmentManager(); 3616267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (parentManager instanceof FragmentManagerImpl) { 3617267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell ((FragmentManagerImpl) parentManager) 3618267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell .dispatchOnFragmentViewDestroyed(f, true); 3619267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3620267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3621805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton for (FragmentLifecycleCallbacksHolder holder : mLifecycleCallbacks) { 3622805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton if (!onlyRecursive || holder.mRecursive) { 3623805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton holder.mCallback.onFragmentViewDestroyed(this, f); 3624267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3625267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3626267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3627267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3628380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton void dispatchOnFragmentDestroyed(@NonNull Fragment f, boolean onlyRecursive) { 3629267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mParent != null) { 3630267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell FragmentManager parentManager = mParent.getFragmentManager(); 3631267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (parentManager instanceof FragmentManagerImpl) { 3632267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell ((FragmentManagerImpl) parentManager) 3633267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell .dispatchOnFragmentDestroyed(f, true); 3634267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3635267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3636805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton for (FragmentLifecycleCallbacksHolder holder : mLifecycleCallbacks) { 3637805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton if (!onlyRecursive || holder.mRecursive) { 3638805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton holder.mCallback.onFragmentDestroyed(this, f); 3639267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3640267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3641267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3642267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3643380e247f873d0adf2be42bd9eb41d02322094f11Jake Wharton void dispatchOnFragmentDetached(@NonNull Fragment f, boolean onlyRecursive) { 3644267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (mParent != null) { 3645267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell FragmentManager parentManager = mParent.getFragmentManager(); 3646267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell if (parentManager instanceof FragmentManagerImpl) { 3647267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell ((FragmentManagerImpl) parentManager) 3648267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell .dispatchOnFragmentDetached(f, true); 3649267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3650267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3651805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton for (FragmentLifecycleCallbacksHolder holder : mLifecycleCallbacks) { 3652805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton if (!onlyRecursive || holder.mRecursive) { 3653805fb8e2508edfc45a1b80a3bf63501aa3507bf2Jake Wharton holder.mCallback.onFragmentDetached(this, f); 3654267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3655267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3656267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell } 3657267b02ebf455fa4d7de59150548676e406b2dd2bAdam Powell 3658cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public static int reverseTransit(int transit) { 3659cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int rev = 0; 3660cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn switch (transit) { 3661cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case FragmentTransaction.TRANSIT_FRAGMENT_OPEN: 3662cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn rev = FragmentTransaction.TRANSIT_FRAGMENT_CLOSE; 3663cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 3664cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case FragmentTransaction.TRANSIT_FRAGMENT_CLOSE: 3665cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn rev = FragmentTransaction.TRANSIT_FRAGMENT_OPEN; 3666cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 3667cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case FragmentTransaction.TRANSIT_FRAGMENT_FADE: 3668cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn rev = FragmentTransaction.TRANSIT_FRAGMENT_FADE; 3669cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 3670cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3671cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return rev; 3672dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3673cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3674dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 36759277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn public static final int ANIM_STYLE_OPEN_ENTER = 1; 36769277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn public static final int ANIM_STYLE_OPEN_EXIT = 2; 36779277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn public static final int ANIM_STYLE_CLOSE_ENTER = 3; 36789277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn public static final int ANIM_STYLE_CLOSE_EXIT = 4; 36799277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn public static final int ANIM_STYLE_FADE_ENTER = 5; 36809277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn public static final int ANIM_STYLE_FADE_EXIT = 6; 3681dea7d510a375df0e0e703bfba5ff63c8acca849eAurimas Liutikas 3682cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn public static int transitToStyleIndex(int transit, boolean enter) { 3683cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn int animAttr = -1; 3684cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn switch (transit) { 3685cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case FragmentTransaction.TRANSIT_FRAGMENT_OPEN: 36869277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn animAttr = enter ? ANIM_STYLE_OPEN_ENTER : ANIM_STYLE_OPEN_EXIT; 3687cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 3688cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case FragmentTransaction.TRANSIT_FRAGMENT_CLOSE: 36899277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn animAttr = enter ? ANIM_STYLE_CLOSE_ENTER : ANIM_STYLE_CLOSE_EXIT; 3690cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 3691cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn case FragmentTransaction.TRANSIT_FRAGMENT_FADE: 36929277b9e4419c1f0b5236d9b573a7cc0b23d56402Dianne Hackborn animAttr = enter ? ANIM_STYLE_FADE_ENTER : ANIM_STYLE_FADE_EXIT; 3693cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn break; 3694cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 3695cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn return animAttr; 3696cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn } 36970f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 36980f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell @Override 3699bf0947be2ead9b3d8e5865bcd3d3652d02a2aa5aChris Banes public View onCreateView(View parent, String name, Context context, AttributeSet attrs) { 37000f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (!"fragment".equals(name)) { 37010f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell return null; 37020f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 37030f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 37040f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell String fname = attrs.getAttributeValue(null, "class"); 37050f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell TypedArray a = context.obtainStyledAttributes(attrs, FragmentTag.Fragment); 37060f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (fname == null) { 37070f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fname = a.getString(FragmentTag.Fragment_name); 37080f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 37090f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell int id = a.getResourceId(FragmentTag.Fragment_id, View.NO_ID); 37100f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell String tag = a.getString(FragmentTag.Fragment_tag); 37110f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell a.recycle(); 37120f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 3713d608cf6e08769bf320c1b595cbbd9a7664160449Todd Kennedy if (!Fragment.isSupportFragmentClass(mHost.getContext(), fname)) { 37140f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // Invalid support lib fragment; let the device's framework handle it. 37150f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // This will allow android.app.Fragments to do the right thing. 37160f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell return null; 37170f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 37180f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 37190f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell int containerId = parent != null ? parent.getId() : 0; 37200f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (containerId == View.NO_ID && id == View.NO_ID && tag == null) { 37210f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell throw new IllegalArgumentException(attrs.getPositionDescription() 37220f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell + ": Must specify unique android:id, android:tag, or have a parent with an id for " + fname); 37230f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 37240f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 37250f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // If we restored from a previous state, we may already have 37260f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // instantiated this fragment from the state and should use 37270f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // that instance instead of making a new one. 37280f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell Fragment fragment = id != View.NO_ID ? findFragmentById(id) : null; 37290f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (fragment == null && tag != null) { 37300f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment = findFragmentByTag(tag); 37310f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 37320f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (fragment == null && containerId != View.NO_ID) { 37330f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment = findFragmentById(containerId); 37340f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 37350f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 37360f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (FragmentManagerImpl.DEBUG) Log.v(TAG, "onCreateView: id=0x" 37370f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell + Integer.toHexString(id) + " fname=" + fname 37380f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell + " existing=" + fragment); 37390f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (fragment == null) { 37404aebb5be19bbf9314e7474dd62df8dd915313436Adam Powell fragment = mContainer.instantiate(context, fname, null); 37410f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mFromLayout = true; 37420f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mFragmentId = id != 0 ? id : containerId; 37430f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mContainerId = containerId; 37440f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mTag = tag; 37450f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mInLayout = true; 37460f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mFragmentManager = this; 37471b84066e4233b4b0c8a32fffc30f95b8cd20ced4Chris Banes fragment.mHost = mHost; 3748b979cb86fa389effb7cd79fa045550c10b7b4819Todd Kennedy fragment.onInflate(mHost.getContext(), attrs, fragment.mSavedFragmentState); 37490f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell addFragment(fragment, true); 37500f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 37510f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } else if (fragment.mInLayout) { 37520f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // A fragment already exists and it is not one we restored from 37530f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // previous state. 37540f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell throw new IllegalArgumentException(attrs.getPositionDescription() 37550f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell + ": Duplicate id 0x" + Integer.toHexString(id) 37560f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell + ", tag " + tag + ", or parent id 0x" + Integer.toHexString(containerId) 37570f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell + " with another fragment for " + fname); 37580f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } else { 37590f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // This fragment was retained from a previous instance; get it 37600f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // going now. 37610f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mInLayout = true; 3762e4148d65bbd62585c68c5782c2081bab6b303568Todd Kennedy fragment.mHost = mHost; 37630f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // If this fragment is newly instantiated (either right now, or 37640f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // from last saved state), then give it the attributes to 37650f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // initialize itself. 37660f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (!fragment.mRetaining) { 3767b979cb86fa389effb7cd79fa045550c10b7b4819Todd Kennedy fragment.onInflate(mHost.getContext(), attrs, fragment.mSavedFragmentState); 37680f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 37690f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 37700f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 37710f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell // If we haven't finished entering the CREATED state ourselves yet, 377237149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell // push the inflated child fragment along. This will ensureInflatedFragmentView 377337149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell // at the right phase of the lifecycle so that we will have mView populated 377437149f137aad1b2ec06df63807cef6713da3ca2fAdam Powell // for compliant fragments below. 37750f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (mCurState < Fragment.CREATED && fragment.mFromLayout) { 37760f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell moveToState(fragment, Fragment.CREATED, 0, 0, false); 37770f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } else { 37780f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell moveToState(fragment); 37790f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 37800f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 37810f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (fragment.mView == null) { 37820f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell throw new IllegalStateException("Fragment " + fname 37830f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell + " did not create a view."); 37840f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 37850f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (id != 0) { 37860f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mView.setId(id); 37870f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 37880f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell if (fragment.mView.getTag() == null) { 37890f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell fragment.mView.setTag(tag); 37900f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 37910f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell return fragment.mView; 37920f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 37930f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 37944bf8c3d1aeb944a993c946db770604b55f981341Aurimas Liutikas @Override 37954bf8c3d1aeb944a993c946db770604b55f981341Aurimas Liutikas public View onCreateView(String name, Context context, AttributeSet attrs) { 37964bf8c3d1aeb944a993c946db770604b55f981341Aurimas Liutikas return onCreateView(null, name, context, attrs); 37974bf8c3d1aeb944a993c946db770604b55f981341Aurimas Liutikas } 37984bf8c3d1aeb944a993c946db770604b55f981341Aurimas Liutikas 37994bf8c3d1aeb944a993c946db770604b55f981341Aurimas Liutikas LayoutInflater.Factory2 getLayoutInflaterFactory() { 38000f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell return this; 38010f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 38020f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 38030f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell static class FragmentTag { 38040f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell public static final int[] Fragment = { 38050f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell 0x01010003, 0x010100d0, 0x010100d1 38060f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell }; 38070f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell public static final int Fragment_id = 1; 38080f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell public static final int Fragment_name = 0; 38090f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell public static final int Fragment_tag = 2; 38100f3dfb28a503b3fb3e51666dd565b0d17eaebfbbAdam Powell } 3811990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3812990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 3813990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * An add or pop transaction to be scheduled for the UI thread. 3814990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 3815990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount interface OpGenerator { 3816990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 3817990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Generate transactions to add to {@code records} and whether or not the transaction is 3818990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * an add or pop to {@code isRecordPop}. 3819990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 3820990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * records and isRecordPop must be added equally so that each transaction in records 3821990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * matches the boolean for whether or not it is a pop in isRecordPop. 3822990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 3823990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param records A list to add transactions to. 3824990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param isRecordPop A list to add whether or not the transactions added to records is 3825990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * a pop transaction. 3826990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @return true if something was added or false otherwise. 3827990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 3828990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount boolean generateOps(ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop); 3829990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3830990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3831990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 3832990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * A pop operation OpGenerator. This will be run on the UI thread and will generate the 3833990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * transactions that will be popped if anything can be popped. 3834990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 3835990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private class PopBackStackState implements OpGenerator { 3836990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final String mName; 3837990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int mId; 3838990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int mFlags; 3839990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3840990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount PopBackStackState(String name, int id, int flags) { 3841990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mName = name; 3842990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mId = id; 3843990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mFlags = flags; 3844990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3845990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3846990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Override 3847990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public boolean generateOps(ArrayList<BackStackRecord> records, 3848990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<Boolean> isRecordPop) { 3849418738949305a8a0e30eba92c125c650048f9c50Adam Powell if (mPrimaryNav != null // We have a primary nav fragment 3850418738949305a8a0e30eba92c125c650048f9c50Adam Powell && mId < 0 // No valid id (since they're local) 3851418738949305a8a0e30eba92c125c650048f9c50Adam Powell && mName == null) { // no name to pop to (since they're local) 3852418738949305a8a0e30eba92c125c650048f9c50Adam Powell final FragmentManager childManager = mPrimaryNav.peekChildFragmentManager(); 3853418738949305a8a0e30eba92c125c650048f9c50Adam Powell if (childManager != null && childManager.popBackStackImmediate()) { 3854418738949305a8a0e30eba92c125c650048f9c50Adam Powell // We didn't add any operations for this FragmentManager even though 3855418738949305a8a0e30eba92c125c650048f9c50Adam Powell // a child did do work. 3856418738949305a8a0e30eba92c125c650048f9c50Adam Powell return false; 3857418738949305a8a0e30eba92c125c650048f9c50Adam Powell } 3858418738949305a8a0e30eba92c125c650048f9c50Adam Powell } 3859990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return popBackStackState(records, isRecordPop, mName, mId, mFlags); 3860990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3861990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3862990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3863990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 3864990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * A listener for a postponed transaction. This waits until 3865990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@link Fragment#startPostponedEnterTransition()} is called or a transaction is started 3866990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * that interacts with this one, based on interactions with the fragment container. 3867990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 3868990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount static class StartEnterTransitionListener 3869990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount implements Fragment.OnStartEnterTransitionListener { 3870990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private final boolean mIsBack; 3871990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private final BackStackRecord mRecord; 3872990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private int mNumPostponed; 3873990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3874990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount StartEnterTransitionListener(BackStackRecord record, boolean isBack) { 3875990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mIsBack = isBack; 3876990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mRecord = record; 3877990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3878990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3879990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 3880990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Called from {@link Fragment#startPostponedEnterTransition()}, this decreases the 3881990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * number of Fragments that are postponed. This may cause the transaction to schedule 3882990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * to finish running and run transitions and animations. 3883990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 3884990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Override 3885990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void onStartEnterTransition() { 3886990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mNumPostponed--; 3887990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (mNumPostponed != 0) { 3888990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return; 3889990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3890990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mRecord.mManager.scheduleCommit(); 3891990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3892990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3893990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 3894990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Called from {@link Fragment# 3895990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * setOnStartEnterTransitionListener(Fragment.OnStartEnterTransitionListener)}, this 3896990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * increases the number of fragments that are postponed as part of this transaction. 3897990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 3898990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Override 3899990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void startListening() { 3900990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mNumPostponed++; 3901990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3902990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3903990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 3904990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @return true if there are no more postponed fragments as part of the transaction. 3905990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 3906990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public boolean isReady() { 3907990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return mNumPostponed == 0; 3908990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3909990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3910990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 3911990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Completes the transaction and start the animations and transitions. This may skip 3912990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * the transitions if this is called before all fragments have called 3913990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@link Fragment#startPostponedEnterTransition()}. 3914990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 3915990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void completeTransaction() { 3916990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final boolean canceled; 3917990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount canceled = mNumPostponed > 0; 3918990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount FragmentManagerImpl manager = mRecord.mManager; 3919990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int numAdded = manager.mAdded.size(); 3920990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numAdded; i++) { 3921990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final Fragment fragment = manager.mAdded.get(i); 3922990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.setOnStartEnterTransitionListener(null); 3923990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (canceled && fragment.isPostponed()) { 3924990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount fragment.startPostponedEnterTransition(); 3925990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3926990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3927990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mRecord.mManager.completeExecute(mRecord, mIsBack, !canceled, true); 3928990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3929990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3930990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 3931990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Cancels this transaction instead of completing it. That means that the state isn't 3932990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * changed, so the pop results in no change to the state. 3933990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 3934990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void cancelTransaction() { 3935990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount mRecord.mManager.completeExecute(mRecord, mIsBack, false, false); 3936990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 3937990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 393815e593ea3575512d7072240d1db9d74fad8749a3George Mount 393915e593ea3575512d7072240d1db9d74fad8749a3George Mount /** 394015e593ea3575512d7072240d1db9d74fad8749a3George Mount * Contains either an animator or animation. One of these should be null. 394115e593ea3575512d7072240d1db9d74fad8749a3George Mount */ 394215e593ea3575512d7072240d1db9d74fad8749a3George Mount private static class AnimationOrAnimator { 394315e593ea3575512d7072240d1db9d74fad8749a3George Mount public final Animation animation; 394415e593ea3575512d7072240d1db9d74fad8749a3George Mount public final Animator animator; 394515e593ea3575512d7072240d1db9d74fad8749a3George Mount 394615e593ea3575512d7072240d1db9d74fad8749a3George Mount private AnimationOrAnimator(Animation animation) { 394715e593ea3575512d7072240d1db9d74fad8749a3George Mount this.animation = animation; 394815e593ea3575512d7072240d1db9d74fad8749a3George Mount this.animator = null; 394915e593ea3575512d7072240d1db9d74fad8749a3George Mount if (animation == null) { 395015e593ea3575512d7072240d1db9d74fad8749a3George Mount throw new IllegalStateException("Animation cannot be null"); 395115e593ea3575512d7072240d1db9d74fad8749a3George Mount } 395215e593ea3575512d7072240d1db9d74fad8749a3George Mount } 395315e593ea3575512d7072240d1db9d74fad8749a3George Mount 395415e593ea3575512d7072240d1db9d74fad8749a3George Mount private AnimationOrAnimator(Animator animator) { 395515e593ea3575512d7072240d1db9d74fad8749a3George Mount this.animation = null; 395615e593ea3575512d7072240d1db9d74fad8749a3George Mount this.animator = animator; 395715e593ea3575512d7072240d1db9d74fad8749a3George Mount if (animator == null) { 395815e593ea3575512d7072240d1db9d74fad8749a3George Mount throw new IllegalStateException("Animator cannot be null"); 395915e593ea3575512d7072240d1db9d74fad8749a3George Mount } 396015e593ea3575512d7072240d1db9d74fad8749a3George Mount } 396115e593ea3575512d7072240d1db9d74fad8749a3George Mount } 396215e593ea3575512d7072240d1db9d74fad8749a3George Mount 396315e593ea3575512d7072240d1db9d74fad8749a3George Mount /** 396415e593ea3575512d7072240d1db9d74fad8749a3George Mount * Wrap an AnimationListener that can be null. This allows us to chain animation listeners. 396515e593ea3575512d7072240d1db9d74fad8749a3George Mount */ 396615e593ea3575512d7072240d1db9d74fad8749a3George Mount private static class AnimationListenerWrapper implements AnimationListener { 396715e593ea3575512d7072240d1db9d74fad8749a3George Mount private final AnimationListener mWrapped; 396815e593ea3575512d7072240d1db9d74fad8749a3George Mount 396915e593ea3575512d7072240d1db9d74fad8749a3George Mount private AnimationListenerWrapper(AnimationListener wrapped) { 397015e593ea3575512d7072240d1db9d74fad8749a3George Mount mWrapped = wrapped; 397115e593ea3575512d7072240d1db9d74fad8749a3George Mount } 397215e593ea3575512d7072240d1db9d74fad8749a3George Mount 397315e593ea3575512d7072240d1db9d74fad8749a3George Mount @CallSuper 397415e593ea3575512d7072240d1db9d74fad8749a3George Mount @Override 397515e593ea3575512d7072240d1db9d74fad8749a3George Mount public void onAnimationStart(Animation animation) { 397615e593ea3575512d7072240d1db9d74fad8749a3George Mount if (mWrapped != null) { 397715e593ea3575512d7072240d1db9d74fad8749a3George Mount mWrapped.onAnimationStart(animation); 397815e593ea3575512d7072240d1db9d74fad8749a3George Mount } 397915e593ea3575512d7072240d1db9d74fad8749a3George Mount } 398015e593ea3575512d7072240d1db9d74fad8749a3George Mount 398115e593ea3575512d7072240d1db9d74fad8749a3George Mount @CallSuper 398215e593ea3575512d7072240d1db9d74fad8749a3George Mount @Override 398315e593ea3575512d7072240d1db9d74fad8749a3George Mount public void onAnimationEnd(Animation animation) { 398415e593ea3575512d7072240d1db9d74fad8749a3George Mount if (mWrapped != null) { 398515e593ea3575512d7072240d1db9d74fad8749a3George Mount mWrapped.onAnimationEnd(animation); 398615e593ea3575512d7072240d1db9d74fad8749a3George Mount } 398715e593ea3575512d7072240d1db9d74fad8749a3George Mount } 398815e593ea3575512d7072240d1db9d74fad8749a3George Mount 398915e593ea3575512d7072240d1db9d74fad8749a3George Mount @CallSuper 399015e593ea3575512d7072240d1db9d74fad8749a3George Mount @Override 399115e593ea3575512d7072240d1db9d74fad8749a3George Mount public void onAnimationRepeat(Animation animation) { 399215e593ea3575512d7072240d1db9d74fad8749a3George Mount if (mWrapped != null) { 399315e593ea3575512d7072240d1db9d74fad8749a3George Mount mWrapped.onAnimationRepeat(animation); 399415e593ea3575512d7072240d1db9d74fad8749a3George Mount } 399515e593ea3575512d7072240d1db9d74fad8749a3George Mount } 399615e593ea3575512d7072240d1db9d74fad8749a3George Mount } 399715e593ea3575512d7072240d1db9d74fad8749a3George Mount 399815e593ea3575512d7072240d1db9d74fad8749a3George Mount /** 399915e593ea3575512d7072240d1db9d74fad8749a3George Mount * Reset the layer type to LAYER_TYPE_NONE at the end of an animation. 400015e593ea3575512d7072240d1db9d74fad8749a3George Mount */ 400115e593ea3575512d7072240d1db9d74fad8749a3George Mount private static class AnimateOnHWLayerIfNeededListener extends AnimationListenerWrapper { 400215e593ea3575512d7072240d1db9d74fad8749a3George Mount View mView; 400315e593ea3575512d7072240d1db9d74fad8749a3George Mount 400415e593ea3575512d7072240d1db9d74fad8749a3George Mount AnimateOnHWLayerIfNeededListener(final View v, AnimationListener listener) { 400515e593ea3575512d7072240d1db9d74fad8749a3George Mount super(listener); 400615e593ea3575512d7072240d1db9d74fad8749a3George Mount mView = v; 400715e593ea3575512d7072240d1db9d74fad8749a3George Mount } 400815e593ea3575512d7072240d1db9d74fad8749a3George Mount 400915e593ea3575512d7072240d1db9d74fad8749a3George Mount @Override 401015e593ea3575512d7072240d1db9d74fad8749a3George Mount @CallSuper 401115e593ea3575512d7072240d1db9d74fad8749a3George Mount public void onAnimationEnd(Animation animation) { 401215e593ea3575512d7072240d1db9d74fad8749a3George Mount // If we're attached to a window, assume we're in the normal performTraversals 401315e593ea3575512d7072240d1db9d74fad8749a3George Mount // drawing path for Animations running. It's not safe to change the layer type 401415e593ea3575512d7072240d1db9d74fad8749a3George Mount // during drawing, so post it to the View to run later. If we're not attached 401515e593ea3575512d7072240d1db9d74fad8749a3George Mount // or we're running on N and above, post it to the view. If we're not on N and 401615e593ea3575512d7072240d1db9d74fad8749a3George Mount // not attached, do it right now since existing platform versions don't run the 401715e593ea3575512d7072240d1db9d74fad8749a3George Mount // hwui renderer for detached views off the UI thread making changing layer type 401815e593ea3575512d7072240d1db9d74fad8749a3George Mount // safe, but posting may not be. 401915e593ea3575512d7072240d1db9d74fad8749a3George Mount // Prior to N posting to a detached view from a non-Looper thread could cause 402015e593ea3575512d7072240d1db9d74fad8749a3George Mount // leaks, since the thread-local run queue on a non-Looper thread would never 402115e593ea3575512d7072240d1db9d74fad8749a3George Mount // be flushed. 402215e593ea3575512d7072240d1db9d74fad8749a3George Mount if (ViewCompat.isAttachedToWindow(mView) || Build.VERSION.SDK_INT >= 24) { 402315e593ea3575512d7072240d1db9d74fad8749a3George Mount mView.post(new Runnable() { 402415e593ea3575512d7072240d1db9d74fad8749a3George Mount @Override 402515e593ea3575512d7072240d1db9d74fad8749a3George Mount public void run() { 402615e593ea3575512d7072240d1db9d74fad8749a3George Mount mView.setLayerType(View.LAYER_TYPE_NONE, null); 402715e593ea3575512d7072240d1db9d74fad8749a3George Mount } 402815e593ea3575512d7072240d1db9d74fad8749a3George Mount }); 402915e593ea3575512d7072240d1db9d74fad8749a3George Mount } else { 403015e593ea3575512d7072240d1db9d74fad8749a3George Mount mView.setLayerType(View.LAYER_TYPE_NONE, null); 403115e593ea3575512d7072240d1db9d74fad8749a3George Mount } 403215e593ea3575512d7072240d1db9d74fad8749a3George Mount super.onAnimationEnd(animation); 403315e593ea3575512d7072240d1db9d74fad8749a3George Mount } 403415e593ea3575512d7072240d1db9d74fad8749a3George Mount } 403515e593ea3575512d7072240d1db9d74fad8749a3George Mount 403615e593ea3575512d7072240d1db9d74fad8749a3George Mount /** 403715e593ea3575512d7072240d1db9d74fad8749a3George Mount * Set the layer type to LAYER_TYPE_HARDWARE while an animator is running. 403815e593ea3575512d7072240d1db9d74fad8749a3George Mount */ 403915e593ea3575512d7072240d1db9d74fad8749a3George Mount private static class AnimatorOnHWLayerIfNeededListener extends AnimatorListenerAdapter { 404015e593ea3575512d7072240d1db9d74fad8749a3George Mount View mView; 404115e593ea3575512d7072240d1db9d74fad8749a3George Mount 404215e593ea3575512d7072240d1db9d74fad8749a3George Mount AnimatorOnHWLayerIfNeededListener(final View v) { 404315e593ea3575512d7072240d1db9d74fad8749a3George Mount mView = v; 404415e593ea3575512d7072240d1db9d74fad8749a3George Mount } 404515e593ea3575512d7072240d1db9d74fad8749a3George Mount 404615e593ea3575512d7072240d1db9d74fad8749a3George Mount @Override 404715e593ea3575512d7072240d1db9d74fad8749a3George Mount public void onAnimationStart(Animator animation) { 404815e593ea3575512d7072240d1db9d74fad8749a3George Mount mView.setLayerType(View.LAYER_TYPE_HARDWARE, null); 404915e593ea3575512d7072240d1db9d74fad8749a3George Mount } 405015e593ea3575512d7072240d1db9d74fad8749a3George Mount 405115e593ea3575512d7072240d1db9d74fad8749a3George Mount @Override 405215e593ea3575512d7072240d1db9d74fad8749a3George Mount public void onAnimationEnd(Animator animation) { 405315e593ea3575512d7072240d1db9d74fad8749a3George Mount mView.setLayerType(View.LAYER_TYPE_NONE, null); 405415e593ea3575512d7072240d1db9d74fad8749a3George Mount animation.removeListener(this); 405515e593ea3575512d7072240d1db9d74fad8749a3George Mount } 405615e593ea3575512d7072240d1db9d74fad8749a3George Mount } 4057e62545fdf58881a2d0426285648f71ce9323ca15George Mount 4058e62545fdf58881a2d0426285648f71ce9323ca15George Mount /** 4059e62545fdf58881a2d0426285648f71ce9323ca15George Mount * We must call endViewTransition() before the animation ends or else the parent doesn't 4060e62545fdf58881a2d0426285648f71ce9323ca15George Mount * get nulled out. We use both startViewTransition() and startAnimation() to solve a problem 4061e62545fdf58881a2d0426285648f71ce9323ca15George Mount * with Views remaining in the hierarchy as disappearing children after the view has been 4062e62545fdf58881a2d0426285648f71ce9323ca15George Mount * removed in some edge cases. 4063e62545fdf58881a2d0426285648f71ce9323ca15George Mount */ 4064e62545fdf58881a2d0426285648f71ce9323ca15George Mount private static class EndViewTransitionAnimator extends AnimationSet implements Runnable { 4065e62545fdf58881a2d0426285648f71ce9323ca15George Mount private final ViewGroup mParent; 4066e62545fdf58881a2d0426285648f71ce9323ca15George Mount private final View mChild; 4067e62545fdf58881a2d0426285648f71ce9323ca15George Mount private boolean mEnded; 4068e62545fdf58881a2d0426285648f71ce9323ca15George Mount private boolean mTransitionEnded; 4069e62545fdf58881a2d0426285648f71ce9323ca15George Mount 4070e62545fdf58881a2d0426285648f71ce9323ca15George Mount EndViewTransitionAnimator(@NonNull Animation animation, 4071e62545fdf58881a2d0426285648f71ce9323ca15George Mount @NonNull ViewGroup parent, @NonNull View child) { 4072e62545fdf58881a2d0426285648f71ce9323ca15George Mount super(false); 4073e62545fdf58881a2d0426285648f71ce9323ca15George Mount mParent = parent; 4074e62545fdf58881a2d0426285648f71ce9323ca15George Mount mChild = child; 4075e62545fdf58881a2d0426285648f71ce9323ca15George Mount addAnimation(animation); 4076e62545fdf58881a2d0426285648f71ce9323ca15George Mount } 4077e62545fdf58881a2d0426285648f71ce9323ca15George Mount 4078e62545fdf58881a2d0426285648f71ce9323ca15George Mount @Override 4079e62545fdf58881a2d0426285648f71ce9323ca15George Mount public boolean getTransformation(long currentTime, Transformation t) { 4080e62545fdf58881a2d0426285648f71ce9323ca15George Mount if (mEnded) { 4081e62545fdf58881a2d0426285648f71ce9323ca15George Mount return !mTransitionEnded; 4082e62545fdf58881a2d0426285648f71ce9323ca15George Mount } 4083e62545fdf58881a2d0426285648f71ce9323ca15George Mount boolean more = super.getTransformation(currentTime, t); 4084e62545fdf58881a2d0426285648f71ce9323ca15George Mount if (!more) { 4085e62545fdf58881a2d0426285648f71ce9323ca15George Mount mEnded = true; 4086d5ba674b175fc0d8a03af60d3c241fc19c623656George Mount OneShotPreDrawListener.add(mParent, this); 4087e62545fdf58881a2d0426285648f71ce9323ca15George Mount } 4088e62545fdf58881a2d0426285648f71ce9323ca15George Mount return true; 4089e62545fdf58881a2d0426285648f71ce9323ca15George Mount } 4090e62545fdf58881a2d0426285648f71ce9323ca15George Mount 4091e62545fdf58881a2d0426285648f71ce9323ca15George Mount @Override 4092e62545fdf58881a2d0426285648f71ce9323ca15George Mount public boolean getTransformation(long currentTime, Transformation outTransformation, 4093e62545fdf58881a2d0426285648f71ce9323ca15George Mount float scale) { 4094e62545fdf58881a2d0426285648f71ce9323ca15George Mount if (mEnded) { 4095e62545fdf58881a2d0426285648f71ce9323ca15George Mount return !mTransitionEnded; 4096e62545fdf58881a2d0426285648f71ce9323ca15George Mount } 4097e62545fdf58881a2d0426285648f71ce9323ca15George Mount boolean more = super.getTransformation(currentTime, outTransformation, scale); 4098e62545fdf58881a2d0426285648f71ce9323ca15George Mount if (!more) { 4099e62545fdf58881a2d0426285648f71ce9323ca15George Mount mEnded = true; 4100d5ba674b175fc0d8a03af60d3c241fc19c623656George Mount OneShotPreDrawListener.add(mParent, this); 4101e62545fdf58881a2d0426285648f71ce9323ca15George Mount } 4102e62545fdf58881a2d0426285648f71ce9323ca15George Mount return true; 4103e62545fdf58881a2d0426285648f71ce9323ca15George Mount } 4104e62545fdf58881a2d0426285648f71ce9323ca15George Mount 4105e62545fdf58881a2d0426285648f71ce9323ca15George Mount @Override 4106e62545fdf58881a2d0426285648f71ce9323ca15George Mount public void run() { 4107e62545fdf58881a2d0426285648f71ce9323ca15George Mount mParent.endViewTransition(mChild); 4108e62545fdf58881a2d0426285648f71ce9323ca15George Mount mTransitionEnded = true; 4109e62545fdf58881a2d0426285648f71ce9323ca15George Mount } 4110e62545fdf58881a2d0426285648f71ce9323ca15George Mount } 4111cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn} 4112