1 /*
2  * Copyright 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package androidx.fragment.app;
18 
19 import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
20 
21 import android.animation.Animator;
22 import android.app.Activity;
23 import android.content.ComponentCallbacks;
24 import android.content.Context;
25 import android.content.Intent;
26 import android.content.IntentSender;
27 import android.content.res.Configuration;
28 import android.content.res.Resources;
29 import android.os.Bundle;
30 import android.os.Looper;
31 import android.os.Parcel;
32 import android.os.Parcelable;
33 import android.util.AttributeSet;
34 import android.util.SparseArray;
35 import android.view.ContextMenu;
36 import android.view.ContextMenu.ContextMenuInfo;
37 import android.view.LayoutInflater;
38 import android.view.Menu;
39 import android.view.MenuInflater;
40 import android.view.MenuItem;
41 import android.view.View;
42 import android.view.View.OnCreateContextMenuListener;
43 import android.view.ViewGroup;
44 import android.view.animation.Animation;
45 import android.widget.AdapterView;
46 
47 import androidx.annotation.CallSuper;
48 import androidx.annotation.MainThread;
49 import androidx.annotation.NonNull;
50 import androidx.annotation.Nullable;
51 import androidx.annotation.RestrictTo;
52 import androidx.annotation.StringRes;
53 import androidx.collection.SimpleArrayMap;
54 import androidx.core.app.SharedElementCallback;
55 import androidx.core.util.DebugUtils;
56 import androidx.core.view.LayoutInflaterCompat;
57 import androidx.lifecycle.Lifecycle;
58 import androidx.lifecycle.LifecycleOwner;
59 import androidx.lifecycle.LifecycleRegistry;
60 import androidx.lifecycle.LiveData;
61 import androidx.lifecycle.MutableLiveData;
62 import androidx.lifecycle.ViewModelStore;
63 import androidx.lifecycle.ViewModelStoreOwner;
64 import androidx.loader.app.LoaderManager;
65 
66 import java.io.FileDescriptor;
67 import java.io.PrintWriter;
68 import java.lang.reflect.InvocationTargetException;
69 
70 /**
71  * Static library support version of the framework's {@link android.app.Fragment}.
72  * Used to write apps that run on platforms prior to Android 3.0.  When running
73  * on Android 3.0 or above, this implementation is still used; it does not try
74  * to switch to the framework's implementation. See the framework {@link android.app.Fragment}
75  * documentation for a class overview.
76  *
77  * <p>The main differences when using this support version instead of the framework version are:
78  * <ul>
79  *  <li>Your activity must extend {@link FragmentActivity}
80  *  <li>You must call {@link FragmentActivity#getSupportFragmentManager} to get the
81  *  {@link FragmentManager}
82  * </ul>
83  *
84  */
85 public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener, LifecycleOwner,
86         ViewModelStoreOwner {
87     private static final SimpleArrayMap<String, Class<?>> sClassMap =
88             new SimpleArrayMap<String, Class<?>>();
89 
90     static final Object USE_DEFAULT_TRANSITION = new Object();
91 
92     static final int INITIALIZING = 0;     // Not yet created.
93     static final int CREATED = 1;          // Created.
94     static final int ACTIVITY_CREATED = 2; // Fully created, not started.
95     static final int STARTED = 3;          // Created and started, not resumed.
96     static final int RESUMED = 4;          // Created started and resumed.
97 
98     int mState = INITIALIZING;
99 
100     // When instantiated from saved state, this is the saved state.
101     Bundle mSavedFragmentState;
102     SparseArray<Parcelable> mSavedViewState;
103     // If the userVisibleHint is changed before the state is set,
104     // it is stored here
105     @Nullable Boolean mSavedUserVisibleHint;
106 
107     // Index into active fragment array.
108     int mIndex = -1;
109 
110     // Internal unique name for this fragment;
111     String mWho;
112 
113     // Construction arguments;
114     Bundle mArguments;
115 
116     // Target fragment.
117     Fragment mTarget;
118 
119     // For use when retaining a fragment: this is the index of the last mTarget.
120     int mTargetIndex = -1;
121 
122     // Target request code.
123     int mTargetRequestCode;
124 
125     // True if the fragment is in the list of added fragments.
126     boolean mAdded;
127 
128     // If set this fragment is being removed from its activity.
129     boolean mRemoving;
130 
131     // Set to true if this fragment was instantiated from a layout file.
132     boolean mFromLayout;
133 
134     // Set to true when the view has actually been inflated in its layout.
135     boolean mInLayout;
136 
137     // True if this fragment has been restored from previously saved state.
138     boolean mRestored;
139 
140     // True if performCreateView has been called and a matching call to performDestroyView
141     // has not yet happened.
142     boolean mPerformedCreateView;
143 
144     // Number of active back stack entries this fragment is in.
145     int mBackStackNesting;
146 
147     // The fragment manager we are associated with.  Set as soon as the
148     // fragment is used in a transaction; cleared after it has been removed
149     // from all transactions.
150     FragmentManagerImpl mFragmentManager;
151 
152     // Host this fragment is attached to.
153     FragmentHostCallback mHost;
154 
155     // Private fragment manager for child fragments inside of this one.
156     FragmentManagerImpl mChildFragmentManager;
157 
158     // For use when restoring fragment state and descendant fragments are retained.
159     // This state is set by FragmentState.instantiate and cleared in onCreate.
160     FragmentManagerNonConfig mChildNonConfig;
161 
162     // ViewModelStore for storing ViewModels associated with this Fragment
163     ViewModelStore mViewModelStore;
164 
165     // If this Fragment is contained in another Fragment, this is that container.
166     Fragment mParentFragment;
167 
168     // The optional identifier for this fragment -- either the container ID if it
169     // was dynamically added to the view hierarchy, or the ID supplied in
170     // layout.
171     int mFragmentId;
172 
173     // When a fragment is being dynamically added to the view hierarchy, this
174     // is the identifier of the parent container it is being added to.
175     int mContainerId;
176 
177     // The optional named tag for this fragment -- usually used to find
178     // fragments that are not part of the layout.
179     String mTag;
180 
181     // Set to true when the app has requested that this fragment be hidden
182     // from the user.
183     boolean mHidden;
184 
185     // Set to true when the app has requested that this fragment be deactivated.
186     boolean mDetached;
187 
188     // If set this fragment would like its instance retained across
189     // configuration changes.
190     boolean mRetainInstance;
191 
192     // If set this fragment is being retained across the current config change.
193     boolean mRetaining;
194 
195     // If set this fragment has menu items to contribute.
196     boolean mHasMenu;
197 
198     // Set to true to allow the fragment's menu to be shown.
199     boolean mMenuVisible = true;
200 
201     // Used to verify that subclasses call through to super class.
202     boolean mCalled;
203 
204     // The parent container of the fragment after dynamically added to UI.
205     ViewGroup mContainer;
206 
207     // The View generated for this fragment.
208     View mView;
209 
210     // The real inner view that will save/restore state.
211     View mInnerView;
212 
213     // Whether this fragment should defer starting until after other fragments
214     // have been started and their loaders are finished.
215     boolean mDeferStart;
216 
217     // Hint provided by the app that this fragment is currently visible to the user.
218     boolean mUserVisibleHint = true;
219 
220     // The animation and transition information for the fragment. This will be null
221     // unless the elements are explicitly accessed and should remain null for Fragments
222     // without Views.
223     AnimationInfo mAnimationInfo;
224 
225     // True if the View was added, and its animation has yet to be run. This could
226     // also indicate that the fragment view hasn't been made visible, even if there is no
227     // animation for this fragment.
228     boolean mIsNewlyAdded;
229 
230     // True if mHidden has been changed and the animation should be scheduled.
231     boolean mHiddenChanged;
232 
233     // The alpha of the view when the view was added and then postponed. If the value is less
234     // than zero, this means that the view's add was canceled and should not participate in
235     // removal animations.
236     float mPostponedAlpha;
237 
238     // The cached value from onGetLayoutInflater(Bundle) that will be returned from
239     // getLayoutInflater()
240     LayoutInflater mLayoutInflater;
241 
242     // Keep track of whether or not this Fragment has run performCreate(). Retained instance
243     // fragments can have mRetaining set to true without going through creation, so we must
244     // track it separately.
245     boolean mIsCreated;
246 
247     LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
248 
249     // These are initialized in performCreateView and unavailable outside of the
250     // onCreateView/onDestroyView lifecycle
251     private LifecycleRegistry mViewLifecycleRegistry;
252     LifecycleOwner mViewLifecycleOwner;
253     MutableLiveData<LifecycleOwner> mViewLifecycleOwnerLiveData = new MutableLiveData<>();
254 
255     @Override
getLifecycle()256     public Lifecycle getLifecycle() {
257         return mLifecycleRegistry;
258     }
259 
260     /**
261      * Get a {@link LifecycleOwner} that represents the {@link #getView() Fragment's View}
262      * lifecycle. In most cases, this mirrors the lifecycle of the Fragment itself, but in cases
263      * of {@link FragmentTransaction#detach(Fragment) detached} Fragments, the lifecycle of the
264      * Fragment can be considerably longer than the lifecycle of the View itself.
265      * <p>
266      * Namely, the lifecycle of the Fragment's View is:
267      * <ol>
268      * <li>{@link Lifecycle.Event#ON_CREATE created} in {@link #onViewStateRestored(Bundle)}</li>
269      * <li>{@link Lifecycle.Event#ON_START started} in {@link #onStart()}</li>
270      * <li>{@link Lifecycle.Event#ON_RESUME resumed} in {@link #onResume()}</li>
271      * <li>{@link Lifecycle.Event#ON_PAUSE paused} in {@link #onPause()}</li>
272      * <li>{@link Lifecycle.Event#ON_STOP stopped} in {@link #onStop()}</li>
273      * <li>{@link Lifecycle.Event#ON_DESTROY destroyed} in {@link #onDestroyView()}</li>
274      * </ol>
275      *
276      * The first method where it is safe to access the view lifecycle is
277      * {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)} under the condition that you must
278      * return a non-null view (an IllegalStateException will be thrown if you access the view
279      * lifecycle but don't return a non-null view).
280      * <p>The view lifecycle remains valid through the call to {@link #onDestroyView()}, after which
281      * {@link #getView()} will return null, the view lifecycle will be destroyed, and this method
282      * will throw an IllegalStateException. Consider using
283      * {@link #getViewLifecycleOwnerLiveData()} or {@link FragmentTransaction#runOnCommit(Runnable)}
284      * to receive a callback for when the Fragment's view lifecycle is available.
285      * <p>
286      * This should only be called on the main thread.
287      *
288      * @return A {@link LifecycleOwner} that represents the {@link #getView() Fragment's View}
289      * lifecycle.
290      * @throws IllegalStateException if the {@link #getView() Fragment's View is null}.
291      */
292     @MainThread
293     @NonNull
getViewLifecycleOwner()294     public LifecycleOwner getViewLifecycleOwner() {
295         if (mViewLifecycleOwner == null) {
296             throw new IllegalStateException("Can't access the Fragment View's LifecycleOwner when "
297                     + "getView() is null i.e., before onCreateView() or after onDestroyView()");
298         }
299         return mViewLifecycleOwner;
300     }
301 
302     /**
303      * Retrieve a {@link LiveData} which allows you to observe the
304      * {@link #getViewLifecycleOwner() lifecycle of the Fragment's View}.
305      * <p>
306      * This will be set to the new {@link LifecycleOwner} after {@link #onCreateView} returns a
307      * non-null View and will set to null after {@link #onDestroyView()}.
308      *
309      * @return A LiveData that changes in sync with {@link #getViewLifecycleOwner()}.
310      */
311     @NonNull
getViewLifecycleOwnerLiveData()312     public LiveData<LifecycleOwner> getViewLifecycleOwnerLiveData() {
313         return mViewLifecycleOwnerLiveData;
314     }
315 
316     @NonNull
317     @Override
getViewModelStore()318     public ViewModelStore getViewModelStore() {
319         if (getContext() == null) {
320             throw new IllegalStateException("Can't access ViewModels from detached fragment");
321         }
322         if (mViewModelStore == null) {
323             mViewModelStore = new ViewModelStore();
324         }
325         return mViewModelStore;
326     }
327 
328     /**
329      * State information that has been retrieved from a fragment instance
330      * through {@link FragmentManager#saveFragmentInstanceState(Fragment)
331      * FragmentManager.saveFragmentInstanceState}.
332      */
333     public static class SavedState implements Parcelable {
334         final Bundle mState;
335 
SavedState(Bundle state)336         SavedState(Bundle state) {
337             mState = state;
338         }
339 
SavedState(Parcel in, ClassLoader loader)340         SavedState(Parcel in, ClassLoader loader) {
341             mState = in.readBundle();
342             if (loader != null && mState != null) {
343                 mState.setClassLoader(loader);
344             }
345         }
346 
347         @Override
describeContents()348         public int describeContents() {
349             return 0;
350         }
351 
352         @Override
writeToParcel(Parcel dest, int flags)353         public void writeToParcel(Parcel dest, int flags) {
354             dest.writeBundle(mState);
355         }
356 
357         public static final Parcelable.Creator<SavedState> CREATOR
358                 = new Parcelable.Creator<SavedState>() {
359             @Override
360             public SavedState createFromParcel(Parcel in) {
361                 return new SavedState(in, null);
362             }
363 
364             @Override
365             public SavedState[] newArray(int size) {
366                 return new SavedState[size];
367             }
368         };
369     }
370 
371     /**
372      * Thrown by {@link Fragment#instantiate(Context, String, Bundle)} when
373      * there is an instantiation failure.
374      */
375     @SuppressWarnings("JavaLangClash")
376     public static class InstantiationException extends RuntimeException {
InstantiationException(String msg, Exception cause)377         public InstantiationException(String msg, Exception cause) {
378             super(msg, cause);
379         }
380     }
381 
382     /**
383      * Default constructor.  <strong>Every</strong> fragment must have an
384      * empty constructor, so it can be instantiated when restoring its
385      * activity's state.  It is strongly recommended that subclasses do not
386      * have other constructors with parameters, since these constructors
387      * will not be called when the fragment is re-instantiated; instead,
388      * arguments can be supplied by the caller with {@link #setArguments}
389      * and later retrieved by the Fragment with {@link #getArguments}.
390      *
391      * <p>Applications should generally not implement a constructor. Prefer
392      * {@link #onAttach(Context)} instead. It is the first place application code can run where
393      * the fragment is ready to be used - the point where the fragment is actually associated with
394      * its context. Some applications may also want to implement {@link #onInflate} to retrieve
395      * attributes from a layout resource, although note this happens when the fragment is attached.
396      */
Fragment()397     public Fragment() {
398     }
399 
400     /**
401      * Like {@link #instantiate(Context, String, Bundle)} but with a null
402      * argument Bundle.
403      */
instantiate(Context context, String fname)404     public static Fragment instantiate(Context context, String fname) {
405         return instantiate(context, fname, null);
406     }
407 
408     /**
409      * Create a new instance of a Fragment with the given class name.  This is
410      * the same as calling its empty constructor.
411      *
412      * @param context The calling context being used to instantiate the fragment.
413      * This is currently just used to get its ClassLoader.
414      * @param fname The class name of the fragment to instantiate.
415      * @param args Bundle of arguments to supply to the fragment, which it
416      * can retrieve with {@link #getArguments()}.  May be null.
417      * @return Returns a new fragment instance.
418      * @throws InstantiationException If there is a failure in instantiating
419      * the given fragment class.  This is a runtime exception; it is not
420      * normally expected to happen.
421      */
instantiate(Context context, String fname, @Nullable Bundle args)422     public static Fragment instantiate(Context context, String fname, @Nullable Bundle args) {
423         try {
424             Class<?> clazz = sClassMap.get(fname);
425             if (clazz == null) {
426                 // Class not found in the cache, see if it's real, and try to add it
427                 clazz = context.getClassLoader().loadClass(fname);
428                 sClassMap.put(fname, clazz);
429             }
430             Fragment f = (Fragment) clazz.getConstructor().newInstance();
431             if (args != null) {
432                 args.setClassLoader(f.getClass().getClassLoader());
433                 f.setArguments(args);
434             }
435             return f;
436         } catch (ClassNotFoundException e) {
437             throw new InstantiationException("Unable to instantiate fragment " + fname
438                     + ": make sure class name exists, is public, and has an"
439                     + " empty constructor that is public", e);
440         } catch (java.lang.InstantiationException e) {
441             throw new InstantiationException("Unable to instantiate fragment " + fname
442                     + ": make sure class name exists, is public, and has an"
443                     + " empty constructor that is public", e);
444         } catch (IllegalAccessException e) {
445             throw new InstantiationException("Unable to instantiate fragment " + fname
446                     + ": make sure class name exists, is public, and has an"
447                     + " empty constructor that is public", e);
448         } catch (NoSuchMethodException e) {
449             throw new InstantiationException("Unable to instantiate fragment " + fname
450                     + ": could not find Fragment constructor", e);
451         } catch (InvocationTargetException e) {
452             throw new InstantiationException("Unable to instantiate fragment " + fname
453                     + ": calling Fragment constructor caused an exception", e);
454         }
455     }
456 
457     /**
458      * Determine if the given fragment name is a support library fragment class.
459      *
460      * @param context Context used to determine the correct ClassLoader to use
461      * @param fname Class name of the fragment to test
462      * @return true if <code>fname</code> is <code>androidx.fragment.app.Fragment</code>
463      *         or a subclass, false otherwise.
464      */
isSupportFragmentClass(Context context, String fname)465     static boolean isSupportFragmentClass(Context context, String fname) {
466         try {
467             Class<?> clazz = sClassMap.get(fname);
468             if (clazz == null) {
469                 // Class not found in the cache, see if it's real, and try to add it
470                 clazz = context.getClassLoader().loadClass(fname);
471                 sClassMap.put(fname, clazz);
472             }
473             return Fragment.class.isAssignableFrom(clazz);
474         } catch (ClassNotFoundException e) {
475             return false;
476         }
477     }
478 
restoreViewState(Bundle savedInstanceState)479     final void restoreViewState(Bundle savedInstanceState) {
480         if (mSavedViewState != null) {
481             mInnerView.restoreHierarchyState(mSavedViewState);
482             mSavedViewState = null;
483         }
484         mCalled = false;
485         onViewStateRestored(savedInstanceState);
486         if (!mCalled) {
487             throw new SuperNotCalledException("Fragment " + this
488                     + " did not call through to super.onViewStateRestored()");
489         }
490     }
491 
setIndex(int index, Fragment parent)492     final void setIndex(int index, Fragment parent) {
493         mIndex = index;
494         if (parent != null) {
495             mWho = parent.mWho + ":" + mIndex;
496         } else {
497             mWho = "android:fragment:" + mIndex;
498         }
499     }
500 
isInBackStack()501     final boolean isInBackStack() {
502         return mBackStackNesting > 0;
503     }
504 
505     /**
506      * Subclasses can not override equals().
507      */
equals(Object o)508     @Override final public boolean equals(Object o) {
509         return super.equals(o);
510     }
511 
512     /**
513      * Subclasses can not override hashCode().
514      */
hashCode()515     @Override final public int hashCode() {
516         return super.hashCode();
517     }
518 
519     @Override
toString()520     public String toString() {
521         StringBuilder sb = new StringBuilder(128);
522         DebugUtils.buildShortClassTag(this, sb);
523         if (mIndex >= 0) {
524             sb.append(" #");
525             sb.append(mIndex);
526         }
527         if (mFragmentId != 0) {
528             sb.append(" id=0x");
529             sb.append(Integer.toHexString(mFragmentId));
530         }
531         if (mTag != null) {
532             sb.append(" ");
533             sb.append(mTag);
534         }
535         sb.append('}');
536         return sb.toString();
537     }
538 
539     /**
540      * Return the identifier this fragment is known by.  This is either
541      * the android:id value supplied in a layout or the container view ID
542      * supplied when adding the fragment.
543      */
getId()544     final public int getId() {
545         return mFragmentId;
546     }
547 
548     /**
549      * Get the tag name of the fragment, if specified.
550      */
551     @Nullable
getTag()552     final public String getTag() {
553         return mTag;
554     }
555 
556     /**
557      * Supply the construction arguments for this fragment.
558      * The arguments supplied here will be retained across fragment destroy and
559      * creation.
560      * <p>This method cannot be called if the fragment is added to a FragmentManager and
561      * if {@link #isStateSaved()} would return true.</p>
562      */
setArguments(@ullable Bundle args)563     public void setArguments(@Nullable Bundle args) {
564         if (mIndex >= 0 && isStateSaved()) {
565             throw new IllegalStateException("Fragment already active and state has been saved");
566         }
567         mArguments = args;
568     }
569 
570     /**
571      * Return the arguments supplied when the fragment was instantiated,
572      * if any.
573      */
574     @Nullable
getArguments()575     final public Bundle getArguments() {
576         return mArguments;
577     }
578 
579     /**
580      * Returns true if this fragment is added and its state has already been saved
581      * by its host. Any operations that would change saved state should not be performed
582      * if this method returns true, and some operations such as {@link #setArguments(Bundle)}
583      * will fail.
584      *
585      * @return true if this fragment's state has already been saved by its host
586      */
isStateSaved()587     public final boolean isStateSaved() {
588         if (mFragmentManager == null) {
589             return false;
590         }
591         return mFragmentManager.isStateSaved();
592     }
593 
594     /**
595      * Set the initial saved state that this Fragment should restore itself
596      * from when first being constructed, as returned by
597      * {@link FragmentManager#saveFragmentInstanceState(Fragment)
598      * FragmentManager.saveFragmentInstanceState}.
599      *
600      * @param state The state the fragment should be restored from.
601      */
setInitialSavedState(@ullable SavedState state)602     public void setInitialSavedState(@Nullable SavedState state) {
603         if (mIndex >= 0) {
604             throw new IllegalStateException("Fragment already active");
605         }
606         mSavedFragmentState = state != null && state.mState != null
607                 ? state.mState : null;
608     }
609 
610     /**
611      * Optional target for this fragment.  This may be used, for example,
612      * if this fragment is being started by another, and when done wants to
613      * give a result back to the first.  The target set here is retained
614      * across instances via {@link FragmentManager#putFragment
615      * FragmentManager.putFragment()}.
616      *
617      * @param fragment The fragment that is the target of this one.
618      * @param requestCode Optional request code, for convenience if you
619      * are going to call back with {@link #onActivityResult(int, int, Intent)}.
620      */
621     @SuppressWarnings("ReferenceEquality")
setTargetFragment(@ullable Fragment fragment, int requestCode)622     public void setTargetFragment(@Nullable Fragment fragment, int requestCode) {
623         // Don't allow a caller to set a target fragment in another FragmentManager,
624         // but there's a snag: people do set target fragments before fragments get added.
625         // We'll have the FragmentManager check that for validity when we move
626         // the fragments to a valid state.
627         final FragmentManager mine = getFragmentManager();
628         final FragmentManager theirs = fragment != null ? fragment.getFragmentManager() : null;
629         if (mine != null && theirs != null && mine != theirs) {
630             throw new IllegalArgumentException("Fragment " + fragment
631                     + " must share the same FragmentManager to be set as a target fragment");
632         }
633 
634         // Don't let someone create a cycle.
635         for (Fragment check = fragment; check != null; check = check.getTargetFragment()) {
636             if (check == this) {
637                 throw new IllegalArgumentException("Setting " + fragment + " as the target of "
638                         + this + " would create a target cycle");
639             }
640         }
641         mTarget = fragment;
642         mTargetRequestCode = requestCode;
643     }
644 
645     /**
646      * Return the target fragment set by {@link #setTargetFragment}.
647      */
648     @Nullable
getTargetFragment()649     final public Fragment getTargetFragment() {
650         return mTarget;
651     }
652 
653     /**
654      * Return the target request code set by {@link #setTargetFragment}.
655      */
getTargetRequestCode()656     final public int getTargetRequestCode() {
657         return mTargetRequestCode;
658     }
659 
660     /**
661      * Return the {@link Context} this fragment is currently associated with.
662      *
663      * @see #requireContext()
664      */
665     @Nullable
getContext()666     public Context getContext() {
667         return mHost == null ? null : mHost.getContext();
668     }
669 
670     /**
671      * Return the {@link Context} this fragment is currently associated with.
672      *
673      * @throws IllegalStateException if not currently associated with a context.
674      * @see #getContext()
675      */
676     @NonNull
requireContext()677     public final Context requireContext() {
678         Context context = getContext();
679         if (context == null) {
680             throw new IllegalStateException("Fragment " + this + " not attached to a context.");
681         }
682         return context;
683     }
684 
685     /**
686      * Return the {@link FragmentActivity} this fragment is currently associated with.
687      * May return {@code null} if the fragment is associated with a {@link Context}
688      * instead.
689      *
690      * @see #requireActivity()
691      */
692     @Nullable
getActivity()693     final public FragmentActivity getActivity() {
694         return mHost == null ? null : (FragmentActivity) mHost.getActivity();
695     }
696 
697     /**
698      * Return the {@link FragmentActivity} this fragment is currently associated with.
699      *
700      * @throws IllegalStateException if not currently associated with an activity or if associated
701      * only with a context.
702      * @see #getActivity()
703      */
704     @NonNull
requireActivity()705     public final FragmentActivity requireActivity() {
706         FragmentActivity activity = getActivity();
707         if (activity == null) {
708             throw new IllegalStateException("Fragment " + this + " not attached to an activity.");
709         }
710         return activity;
711     }
712 
713     /**
714      * Return the host object of this fragment. May return {@code null} if the fragment
715      * isn't currently being hosted.
716      *
717      * @see #requireHost()
718      */
719     @Nullable
getHost()720     final public Object getHost() {
721         return mHost == null ? null : mHost.onGetHost();
722     }
723 
724     /**
725      * Return the host object of this fragment.
726      *
727      * @throws IllegalStateException if not currently associated with a host.
728      * @see #getHost()
729      */
730     @NonNull
requireHost()731     public final Object requireHost() {
732         Object host = getHost();
733         if (host == null) {
734             throw new IllegalStateException("Fragment " + this + " not attached to a host.");
735         }
736         return host;
737     }
738 
739     /**
740      * Return <code>requireActivity().getResources()</code>.
741      */
742     @NonNull
getResources()743     final public Resources getResources() {
744         return requireContext().getResources();
745     }
746 
747     /**
748      * Return a localized, styled CharSequence from the application's package's
749      * default string table.
750      *
751      * @param resId Resource id for the CharSequence text
752      */
753     @NonNull
getText(@tringRes int resId)754     public final CharSequence getText(@StringRes int resId) {
755         return getResources().getText(resId);
756     }
757 
758     /**
759      * Return a localized string from the application's package's
760      * default string table.
761      *
762      * @param resId Resource id for the string
763      */
764     @NonNull
getString(@tringRes int resId)765     public final String getString(@StringRes int resId) {
766         return getResources().getString(resId);
767     }
768 
769     /**
770      * Return a localized formatted string from the application's package's
771      * default string table, substituting the format arguments as defined in
772      * {@link java.util.Formatter} and {@link java.lang.String#format}.
773      *
774      * @param resId Resource id for the format string
775      * @param formatArgs The format arguments that will be used for substitution.
776      */
777     @NonNull
getString(@tringRes int resId, Object... formatArgs)778     public final String getString(@StringRes int resId, Object... formatArgs) {
779         return getResources().getString(resId, formatArgs);
780     }
781 
782     /**
783      * Return the FragmentManager for interacting with fragments associated
784      * with this fragment's activity.  Note that this will be non-null slightly
785      * before {@link #getActivity()}, during the time from when the fragment is
786      * placed in a {@link FragmentTransaction} until it is committed and
787      * attached to its activity.
788      *
789      * <p>If this Fragment is a child of another Fragment, the FragmentManager
790      * returned here will be the parent's {@link #getChildFragmentManager()}.
791      *
792      * @see #requireFragmentManager()
793      */
794     @Nullable
getFragmentManager()795     final public FragmentManager getFragmentManager() {
796         return mFragmentManager;
797     }
798 
799     /**
800      * Return the FragmentManager for interacting with fragments associated
801      * with this fragment's activity.  Note that this will available slightly
802      * before {@link #getActivity()}, during the time from when the fragment is
803      * placed in a {@link FragmentTransaction} until it is committed and
804      * attached to its activity.
805      *
806      * <p>If this Fragment is a child of another Fragment, the FragmentManager
807      * returned here will be the parent's {@link #getChildFragmentManager()}.
808      *
809      * @throws IllegalStateException if not associated with a transaction or host.
810      * @see #getFragmentManager()
811      */
812     @NonNull
requireFragmentManager()813     public final FragmentManager requireFragmentManager() {
814         FragmentManager fragmentManager = getFragmentManager();
815         if (fragmentManager == null) {
816             throw new IllegalStateException(
817                     "Fragment " + this + " not associated with a fragment manager.");
818         }
819         return fragmentManager;
820     }
821 
822     /**
823      * Return a private FragmentManager for placing and managing Fragments
824      * inside of this Fragment.
825      */
826     @NonNull
getChildFragmentManager()827     final public FragmentManager getChildFragmentManager() {
828         if (mChildFragmentManager == null) {
829             instantiateChildFragmentManager();
830             if (mState >= RESUMED) {
831                 mChildFragmentManager.dispatchResume();
832             } else if (mState >= STARTED) {
833                 mChildFragmentManager.dispatchStart();
834             } else if (mState >= ACTIVITY_CREATED) {
835                 mChildFragmentManager.dispatchActivityCreated();
836             } else if (mState >= CREATED) {
837                 mChildFragmentManager.dispatchCreate();
838             }
839         }
840         return mChildFragmentManager;
841     }
842 
843     /**
844      * Return this fragment's child FragmentManager one has been previously created,
845      * otherwise null.
846      */
847     @Nullable
peekChildFragmentManager()848     FragmentManager peekChildFragmentManager() {
849         return mChildFragmentManager;
850     }
851 
852     /**
853      * Returns the parent Fragment containing this Fragment.  If this Fragment
854      * is attached directly to an Activity, returns null.
855      */
856     @Nullable
getParentFragment()857     final public Fragment getParentFragment() {
858         return mParentFragment;
859     }
860 
861     /**
862      * Return true if the fragment is currently added to its activity.
863      */
isAdded()864     final public boolean isAdded() {
865         return mHost != null && mAdded;
866     }
867 
868     /**
869      * Return true if the fragment has been explicitly detached from the UI.
870      * That is, {@link FragmentTransaction#detach(Fragment)
871      * FragmentTransaction.detach(Fragment)} has been used on it.
872      */
isDetached()873     final public boolean isDetached() {
874         return mDetached;
875     }
876 
877     /**
878      * Return true if this fragment is currently being removed from its
879      * activity.  This is  <em>not</em> whether its activity is finishing, but
880      * rather whether it is in the process of being removed from its activity.
881      */
isRemoving()882     final public boolean isRemoving() {
883         return mRemoving;
884     }
885 
886     /**
887      * Return true if the layout is included as part of an activity view
888      * hierarchy via the &lt;fragment&gt; tag.  This will always be true when
889      * fragments are created through the &lt;fragment&gt; tag, <em>except</em>
890      * in the case where an old fragment is restored from a previous state and
891      * it does not appear in the layout of the current state.
892      */
isInLayout()893     final public boolean isInLayout() {
894         return mInLayout;
895     }
896 
897     /**
898      * Return true if the fragment is in the resumed state.  This is true
899      * for the duration of {@link #onResume()} and {@link #onPause()} as well.
900      */
isResumed()901     final public boolean isResumed() {
902         return mState >= RESUMED;
903     }
904 
905     /**
906      * Return true if the fragment is currently visible to the user.  This means
907      * it: (1) has been added, (2) has its view attached to the window, and
908      * (3) is not hidden.
909      */
isVisible()910     final public boolean isVisible() {
911         return isAdded() && !isHidden() && mView != null
912                 && mView.getWindowToken() != null && mView.getVisibility() == View.VISIBLE;
913     }
914 
915     /**
916      * Return true if the fragment has been hidden.  By default fragments
917      * are shown.  You can find out about changes to this state with
918      * {@link #onHiddenChanged}.  Note that the hidden state is orthogonal
919      * to other states -- that is, to be visible to the user, a fragment
920      * must be both started and not hidden.
921      */
isHidden()922     final public boolean isHidden() {
923         return mHidden;
924     }
925 
926     /** @hide */
927     @RestrictTo(LIBRARY_GROUP)
hasOptionsMenu()928     final public boolean hasOptionsMenu() {
929         return mHasMenu;
930     }
931 
932     /** @hide */
933     @RestrictTo(LIBRARY_GROUP)
isMenuVisible()934     final public boolean isMenuVisible() {
935         return mMenuVisible;
936     }
937 
938     /**
939      * Called when the hidden state (as returned by {@link #isHidden()} of
940      * the fragment has changed.  Fragments start out not hidden; this will
941      * be called whenever the fragment changes state from that.
942      * @param hidden True if the fragment is now hidden, false otherwise.
943      */
onHiddenChanged(boolean hidden)944     public void onHiddenChanged(boolean hidden) {
945     }
946 
947     /**
948      * Control whether a fragment instance is retained across Activity
949      * re-creation (such as from a configuration change).  This can only
950      * be used with fragments not in the back stack.  If set, the fragment
951      * lifecycle will be slightly different when an activity is recreated:
952      * <ul>
953      * <li> {@link #onDestroy()} will not be called (but {@link #onDetach()} still
954      * will be, because the fragment is being detached from its current activity).
955      * <li> {@link #onCreate(Bundle)} will not be called since the fragment
956      * is not being re-created.
957      * <li> {@link #onAttach(Activity)} and {@link #onActivityCreated(Bundle)} <b>will</b>
958      * still be called.
959      * </ul>
960      */
setRetainInstance(boolean retain)961     public void setRetainInstance(boolean retain) {
962         mRetainInstance = retain;
963     }
964 
getRetainInstance()965     final public boolean getRetainInstance() {
966         return mRetainInstance;
967     }
968 
969     /**
970      * Report that this fragment would like to participate in populating
971      * the options menu by receiving a call to {@link #onCreateOptionsMenu}
972      * and related methods.
973      *
974      * @param hasMenu If true, the fragment has menu items to contribute.
975      */
setHasOptionsMenu(boolean hasMenu)976     public void setHasOptionsMenu(boolean hasMenu) {
977         if (mHasMenu != hasMenu) {
978             mHasMenu = hasMenu;
979             if (isAdded() && !isHidden()) {
980                 mHost.onSupportInvalidateOptionsMenu();
981             }
982         }
983     }
984 
985     /**
986      * Set a hint for whether this fragment's menu should be visible.  This
987      * is useful if you know that a fragment has been placed in your view
988      * hierarchy so that the user can not currently seen it, so any menu items
989      * it has should also not be shown.
990      *
991      * @param menuVisible The default is true, meaning the fragment's menu will
992      * be shown as usual.  If false, the user will not see the menu.
993      */
setMenuVisibility(boolean menuVisible)994     public void setMenuVisibility(boolean menuVisible) {
995         if (mMenuVisible != menuVisible) {
996             mMenuVisible = menuVisible;
997             if (mHasMenu && isAdded() && !isHidden()) {
998                 mHost.onSupportInvalidateOptionsMenu();
999             }
1000         }
1001     }
1002 
1003     /**
1004      * Set a hint to the system about whether this fragment's UI is currently visible
1005      * to the user. This hint defaults to true and is persistent across fragment instance
1006      * state save and restore.
1007      *
1008      * <p>An app may set this to false to indicate that the fragment's UI is
1009      * scrolled out of visibility or is otherwise not directly visible to the user.
1010      * This may be used by the system to prioritize operations such as fragment lifecycle updates
1011      * or loader ordering behavior.</p>
1012      *
1013      * <p><strong>Note:</strong> This method may be called outside of the fragment lifecycle.
1014      * and thus has no ordering guarantees with regard to fragment lifecycle method calls.</p>
1015      *
1016      * @param isVisibleToUser true if this fragment's UI is currently visible to the user (default),
1017      *                        false if it is not.
1018      */
setUserVisibleHint(boolean isVisibleToUser)1019     public void setUserVisibleHint(boolean isVisibleToUser) {
1020         if (!mUserVisibleHint && isVisibleToUser && mState < STARTED
1021                 && mFragmentManager != null && isAdded() && mIsCreated) {
1022             mFragmentManager.performPendingDeferredStart(this);
1023         }
1024         mUserVisibleHint = isVisibleToUser;
1025         mDeferStart = mState < STARTED && !isVisibleToUser;
1026         if (mSavedFragmentState != null) {
1027             // Ensure that if the user visible hint is set before the Fragment has
1028             // restored its state that we don't lose the new value
1029             mSavedUserVisibleHint = isVisibleToUser;
1030         }
1031     }
1032 
1033     /**
1034      * @return The current value of the user-visible hint on this fragment.
1035      * @see #setUserVisibleHint(boolean)
1036      */
1037     public boolean getUserVisibleHint() {
1038         return mUserVisibleHint;
1039     }
1040 
1041     /**
1042      * Return the LoaderManager for this fragment.
1043      *
1044      * @deprecated Use
1045      * {@link LoaderManager#getInstance(LifecycleOwner) LoaderManager.getInstance(this)}.
1046      */
1047     @Deprecated
1048     public LoaderManager getLoaderManager() {
1049         return LoaderManager.getInstance(this);
1050     }
1051 
1052     /**
1053      * Call {@link Activity#startActivity(Intent)} from the fragment's
1054      * containing Activity.
1055      */
1056     public void startActivity(Intent intent) {
1057         startActivity(intent, null);
1058     }
1059 
1060     /**
1061      * Call {@link Activity#startActivity(Intent, Bundle)} from the fragment's
1062      * containing Activity.
1063      */
1064     public void startActivity(Intent intent, @Nullable Bundle options) {
1065         if (mHost == null) {
1066             throw new IllegalStateException("Fragment " + this + " not attached to Activity");
1067         }
1068         mHost.onStartActivityFromFragment(this /*fragment*/, intent, -1, options);
1069     }
1070 
1071     /**
1072      * Call {@link Activity#startActivityForResult(Intent, int)} from the fragment's
1073      * containing Activity.
1074      */
1075     public void startActivityForResult(Intent intent, int requestCode) {
1076         startActivityForResult(intent, requestCode, null);
1077     }
1078 
1079     /**
1080      * Call {@link Activity#startActivityForResult(Intent, int, Bundle)} from the fragment's
1081      * containing Activity.
1082      */
1083     public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
1084         if (mHost == null) {
1085             throw new IllegalStateException("Fragment " + this + " not attached to Activity");
1086         }
1087         mHost.onStartActivityFromFragment(this /*fragment*/, intent, requestCode, options);
1088     }
1089 
1090     /**
1091      * Call {@link Activity#startIntentSenderForResult(IntentSender, int, Intent, int, int, int,
1092      * Bundle)} from the fragment's containing Activity.
1093      */
1094     public void startIntentSenderForResult(IntentSender intent, int requestCode,
1095             @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
1096             Bundle options) throws IntentSender.SendIntentException {
1097         if (mHost == null) {
1098             throw new IllegalStateException("Fragment " + this + " not attached to Activity");
1099         }
1100         mHost.onStartIntentSenderFromFragment(this, intent, requestCode, fillInIntent, flagsMask,
1101                 flagsValues, extraFlags, options);
1102     }
1103 
1104     /**
1105      * Receive the result from a previous call to
1106      * {@link #startActivityForResult(Intent, int)}.  This follows the
1107      * related Activity API as described there in
1108      * {@link Activity#onActivityResult(int, int, Intent)}.
1109      *
1110      * @param requestCode The integer request code originally supplied to
1111      *                    startActivityForResult(), allowing you to identify who this
1112      *                    result came from.
1113      * @param resultCode The integer result code returned by the child activity
1114      *                   through its setResult().
1115      * @param data An Intent, which can return result data to the caller
1116      *               (various data can be attached to Intent "extras").
1117      */
1118     public void onActivityResult(int requestCode, int resultCode, Intent data) {
1119     }
1120 
1121     /**
1122      * Requests permissions to be granted to this application. These permissions
1123      * must be requested in your manifest, they should not be granted to your app,
1124      * and they should have protection level {@link android.content.pm.PermissionInfo
1125      * #PROTECTION_DANGEROUS dangerous}, regardless whether they are declared by
1126      * the platform or a third-party app.
1127      * <p>
1128      * Normal permissions {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL}
1129      * are granted at install time if requested in the manifest. Signature permissions
1130      * {@link android.content.pm.PermissionInfo#PROTECTION_SIGNATURE} are granted at
1131      * install time if requested in the manifest and the signature of your app matches
1132      * the signature of the app declaring the permissions.
1133      * </p>
1134      * <p>
1135      * If your app does not have the requested permissions the user will be presented
1136      * with UI for accepting them. After the user has accepted or rejected the
1137      * requested permissions you will receive a callback on {@link
1138      * #onRequestPermissionsResult(int, String[], int[])} reporting whether the
1139      * permissions were granted or not.
1140      * </p>
1141      * <p>
1142      * Note that requesting a permission does not guarantee it will be granted and
1143      * your app should be able to run without having this permission.
1144      * </p>
1145      * <p>
1146      * This method may start an activity allowing the user to choose which permissions
1147      * to grant and which to reject. Hence, you should be prepared that your activity
1148      * may be paused and resumed. Further, granting some permissions may require
1149      * a restart of you application. In such a case, the system will recreate the
1150      * activity stack before delivering the result to {@link
1151      * #onRequestPermissionsResult(int, String[], int[])}.
1152      * </p>
1153      * <p>
1154      * When checking whether you have a permission you should use {@link
1155      * android.content.Context#checkSelfPermission(String)}.
1156      * </p>
1157      * <p>
1158      * Calling this API for permissions already granted to your app would show UI
1159      * to the user to decided whether the app can still hold these permissions. This
1160      * can be useful if the way your app uses the data guarded by the permissions
1161      * changes significantly.
1162      * </p>
1163      * <p>
1164      * A sample permissions request looks like this:
1165      * </p>
1166      * <code><pre><p>
1167      * private void showContacts() {
1168      *     if (getActivity().checkSelfPermission(Manifest.permission.READ_CONTACTS)
1169      *             != PackageManager.PERMISSION_GRANTED) {
1170      *         requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},
1171      *                 PERMISSIONS_REQUEST_READ_CONTACTS);
1172      *     } else {
1173      *         doShowContacts();
1174      *     }
1175      * }
1176      *
1177      * {@literal @}Override
1178      * public void onRequestPermissionsResult(int requestCode, String[] permissions,
1179      *         int[] grantResults) {
1180      *     if (requestCode == PERMISSIONS_REQUEST_READ_CONTACTS
1181      *             && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
1182      *         doShowContacts();
1183      *     }
1184      * }
1185      * </code></pre></p>
1186      *
1187      * @param permissions The requested permissions.
1188      * @param requestCode Application specific request code to match with a result
1189      *    reported to {@link #onRequestPermissionsResult(int, String[], int[])}.
1190      *
1191      * @see #onRequestPermissionsResult(int, String[], int[])
1192      * @see android.content.Context#checkSelfPermission(String)
1193      */
1194     public final void requestPermissions(@NonNull String[] permissions, int requestCode) {
1195         if (mHost == null) {
1196             throw new IllegalStateException("Fragment " + this + " not attached to Activity");
1197         }
1198         mHost.onRequestPermissionsFromFragment(this, permissions, requestCode);
1199     }
1200 
1201     /**
1202      * Callback for the result from requesting permissions. This method
1203      * is invoked for every call on {@link #requestPermissions(String[], int)}.
1204      * <p>
1205      * <strong>Note:</strong> It is possible that the permissions request interaction
1206      * with the user is interrupted. In this case you will receive empty permissions
1207      * and results arrays which should be treated as a cancellation.
1208      * </p>
1209      *
1210      * @param requestCode The request code passed in {@link #requestPermissions(String[], int)}.
1211      * @param permissions The requested permissions. Never null.
1212      * @param grantResults The grant results for the corresponding permissions
1213      *     which is either {@link android.content.pm.PackageManager#PERMISSION_GRANTED}
1214      *     or {@link android.content.pm.PackageManager#PERMISSION_DENIED}. Never null.
1215      *
1216      * @see #requestPermissions(String[], int)
1217      */
1218     public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
1219             @NonNull int[] grantResults) {
1220         /* callback - do nothing */
1221     }
1222 
1223     /**
1224      * Gets whether you should show UI with rationale for requesting a permission.
1225      * You should do this only if you do not have the permission and the context in
1226      * which the permission is requested does not clearly communicate to the user
1227      * what would be the benefit from granting this permission.
1228      * <p>
1229      * For example, if you write a camera app, requesting the camera permission
1230      * would be expected by the user and no rationale for why it is requested is
1231      * needed. If however, the app needs location for tagging photos then a non-tech
1232      * savvy user may wonder how location is related to taking photos. In this case
1233      * you may choose to show UI with rationale of requesting this permission.
1234      * </p>
1235      *
1236      * @param permission A permission your app wants to request.
1237      * @return Whether you can show permission rationale UI.
1238      *
1239      * @see Context#checkSelfPermission(String)
1240      * @see #requestPermissions(String[], int)
1241      * @see #onRequestPermissionsResult(int, String[], int[])
1242      */
1243     public boolean shouldShowRequestPermissionRationale(@NonNull String permission) {
1244         if (mHost != null) {
1245             return mHost.onShouldShowRequestPermissionRationale(permission);
1246         }
1247         return false;
1248     }
1249 
1250     /**
1251      * Returns the LayoutInflater used to inflate Views of this Fragment. The default
1252      * implementation will throw an exception if the Fragment is not attached.
1253      *
1254      * @param savedInstanceState If the fragment is being re-created from
1255      * a previous saved state, this is the state.
1256      * @return The LayoutInflater used to inflate Views of this Fragment.
1257      */
1258     @NonNull
1259     public LayoutInflater onGetLayoutInflater(@Nullable Bundle savedInstanceState) {
1260         // TODO: move the implementation in getLayoutInflater to here
1261         return getLayoutInflater(savedInstanceState);
1262     }
1263 
1264     /**
1265      * Returns the cached LayoutInflater used to inflate Views of this Fragment. If
1266      * {@link #onGetLayoutInflater(Bundle)} has not been called {@link #onGetLayoutInflater(Bundle)}
1267      * will be called with a {@code null} argument and that value will be cached.
1268      * <p>
1269      * The cached LayoutInflater will be replaced immediately prior to
1270      * {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)} and cleared immediately after
1271      * {@link #onDetach()}.
1272      *
1273      * @return The LayoutInflater used to inflate Views of this Fragment.
1274      */
1275     public final LayoutInflater getLayoutInflater() {
1276         if (mLayoutInflater == null) {
1277             return performGetLayoutInflater(null);
1278         }
1279         return mLayoutInflater;
1280     }
1281 
1282     /**
1283      * Calls {@link #onGetLayoutInflater(Bundle)} and caches the result for use by
1284      * {@link #getLayoutInflater()}.
1285      *
1286      * @param savedInstanceState If the fragment is being re-created from
1287      * a previous saved state, this is the state.
1288      * @return The LayoutInflater used to inflate Views of this Fragment.
1289      */
1290     @NonNull
1291     LayoutInflater performGetLayoutInflater(@Nullable Bundle savedInstanceState) {
1292         LayoutInflater layoutInflater = onGetLayoutInflater(savedInstanceState);
1293         mLayoutInflater = layoutInflater;
1294         return mLayoutInflater;
1295     }
1296 
1297     /**
1298      * Override {@link #onGetLayoutInflater(Bundle)} when you need to change the
1299      * LayoutInflater or call {@link #getLayoutInflater()} when you want to
1300      * retrieve the current LayoutInflater.
1301      *
1302      * @hide
1303      * @deprecated Override {@link #onGetLayoutInflater(Bundle)} or call
1304      * {@link #getLayoutInflater()} instead of this method.
1305      */
1306     @Deprecated
1307     @NonNull
1308     @RestrictTo(LIBRARY_GROUP)
1309     public LayoutInflater getLayoutInflater(@Nullable Bundle savedFragmentState) {
1310         if (mHost == null) {
1311             throw new IllegalStateException("onGetLayoutInflater() cannot be executed until the "
1312                     + "Fragment is attached to the FragmentManager.");
1313         }
1314         LayoutInflater result = mHost.onGetLayoutInflater();
1315         getChildFragmentManager(); // Init if needed; use raw implementation below.
1316         LayoutInflaterCompat.setFactory2(result, mChildFragmentManager.getLayoutInflaterFactory());
1317         return result;
1318     }
1319 
1320     /**
1321      * Called when a fragment is being created as part of a view layout
1322      * inflation, typically from setting the content view of an activity.  This
1323      * may be called immediately after the fragment is created from a <fragment>
1324      * tag in a layout file.  Note this is <em>before</em> the fragment's
1325      * {@link #onAttach(Activity)} has been called; all you should do here is
1326      * parse the attributes and save them away.
1327      *
1328      * <p>This is called every time the fragment is inflated, even if it is
1329      * being inflated into a new instance with saved state.  It typically makes
1330      * sense to re-parse the parameters each time, to allow them to change with
1331      * different configurations.</p>
1332      *
1333      * <p>Here is a typical implementation of a fragment that can take parameters
1334      * both through attributes supplied here as well from {@link #getArguments()}:</p>
1335      *
1336      * {@sample frameworks/support/samples/Support4Demos/src/main/java/com/example/android/supportv4/app/FragmentArgumentsSupport.java
1337      *      fragment}
1338      *
1339      * <p>Note that parsing the XML attributes uses a "styleable" resource.  The
1340      * declaration for the styleable used here is:</p>
1341      *
1342      * {@sample frameworks/support/samples/Support4Demos/src/main/res/values/attrs.xml fragment_arguments}
1343      *
1344      * <p>The fragment can then be declared within its activity's content layout
1345      * through a tag like this:</p>
1346      *
1347      * {@sample frameworks/support/samples/Support4Demos/src/main/res/layout/fragment_arguments_support.xml from_attributes}
1348      *
1349      * <p>This fragment can also be created dynamically from arguments given
1350      * at runtime in the arguments Bundle; here is an example of doing so at
1351      * creation of the containing activity:</p>
1352      *
1353      * {@sample frameworks/support/samples/Support4Demos/src/main/java/com/example/android/supportv4/app/FragmentArgumentsSupport.java
1354      *      create}
1355      *
1356      * @param context The Activity that is inflating this fragment.
1357      * @param attrs The attributes at the tag where the fragment is
1358      * being created.
1359      * @param savedInstanceState If the fragment is being re-created from
1360      * a previous saved state, this is the state.
1361      */
1362     @CallSuper
1363     public void onInflate(Context context, AttributeSet attrs, Bundle savedInstanceState) {
1364         mCalled = true;
1365         final Activity hostActivity = mHost == null ? null : mHost.getActivity();
1366         if (hostActivity != null) {
1367             mCalled = false;
1368             onInflate(hostActivity, attrs, savedInstanceState);
1369         }
1370     }
1371 
1372     /**
1373      * Called when a fragment is being created as part of a view layout
1374      * inflation, typically from setting the content view of an activity.
1375      *
1376      * @deprecated See {@link #onInflate(Context, AttributeSet, Bundle)}.
1377      */
1378     @Deprecated
1379     @CallSuper
1380     public void onInflate(Activity activity, AttributeSet attrs, Bundle savedInstanceState) {
1381         mCalled = true;
1382     }
1383 
1384     /**
1385      * Called when a fragment is attached as a child of this fragment.
1386      *
1387      * <p>This is called after the attached fragment's <code>onAttach</code> and before
1388      * the attached fragment's <code>onCreate</code> if the fragment has not yet had a previous
1389      * call to <code>onCreate</code>.</p>
1390      *
1391      * @param childFragment child fragment being attached
1392      */
1393     public void onAttachFragment(Fragment childFragment) {
1394     }
1395 
1396     /**
1397      * Called when a fragment is first attached to its context.
1398      * {@link #onCreate(Bundle)} will be called after this.
1399      */
1400     @CallSuper
1401     public void onAttach(Context context) {
1402         mCalled = true;
1403         final Activity hostActivity = mHost == null ? null : mHost.getActivity();
1404         if (hostActivity != null) {
1405             mCalled = false;
1406             onAttach(hostActivity);
1407         }
1408     }
1409 
1410     /**
1411      * Called when a fragment is first attached to its activity.
1412      * {@link #onCreate(Bundle)} will be called after this.
1413      *
1414      * @deprecated See {@link #onAttach(Context)}.
1415      */
1416     @Deprecated
1417     @CallSuper
1418     public void onAttach(Activity activity) {
1419         mCalled = true;
1420     }
1421 
1422     /**
1423      * Called when a fragment loads an animation. Note that if
1424      * {@link FragmentTransaction#setCustomAnimations(int, int)} was called with
1425      * {@link Animator} resources instead of {@link Animation} resources, {@code nextAnim}
1426      * will be an animator resource.
1427      *
1428      * @param transit The value set in {@link FragmentTransaction#setTransition(int)} or 0 if not
1429      *                set.
1430      * @param enter {@code true} when the fragment is added/attached/shown or {@code false} when
1431      *              the fragment is removed/detached/hidden.
1432      * @param nextAnim The resource set in
1433      *                 {@link FragmentTransaction#setCustomAnimations(int, int)},
1434      *                 {@link FragmentTransaction#setCustomAnimations(int, int, int, int)}, or
1435      *                 0 if neither was called. The value will depend on the current operation.
1436      */
1437     public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
1438         return null;
1439     }
1440 
1441     /**
1442      * Called when a fragment loads an animator. This will be called when
1443      * {@link #onCreateAnimation(int, boolean, int)} returns null. Note that if
1444      * {@link FragmentTransaction#setCustomAnimations(int, int)} was called with
1445      * {@link Animation} resources instead of {@link Animator} resources, {@code nextAnim}
1446      * will be an animation resource.
1447      *
1448      * @param transit The value set in {@link FragmentTransaction#setTransition(int)} or 0 if not
1449      *                set.
1450      * @param enter {@code true} when the fragment is added/attached/shown or {@code false} when
1451      *              the fragment is removed/detached/hidden.
1452      * @param nextAnim The resource set in
1453      *                 {@link FragmentTransaction#setCustomAnimations(int, int)},
1454      *                 {@link FragmentTransaction#setCustomAnimations(int, int, int, int)}, or
1455      *                 0 if neither was called. The value will depend on the current operation.
1456      */
1457     public Animator onCreateAnimator(int transit, boolean enter, int nextAnim) {
1458         return null;
1459     }
1460 
1461     /**
1462      * Called to do initial creation of a fragment.  This is called after
1463      * {@link #onAttach(Activity)} and before
1464      * {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}.
1465      *
1466      * <p>Note that this can be called while the fragment's activity is
1467      * still in the process of being created.  As such, you can not rely
1468      * on things like the activity's content view hierarchy being initialized
1469      * at this point.  If you want to do work once the activity itself is
1470      * created, see {@link #onActivityCreated(Bundle)}.
1471      *
1472      * <p>Any restored child fragments will be created before the base
1473      * <code>Fragment.onCreate</code> method returns.</p>
1474      *
1475      * @param savedInstanceState If the fragment is being re-created from
1476      * a previous saved state, this is the state.
1477      */
1478     @CallSuper
1479     public void onCreate(@Nullable Bundle savedInstanceState) {
1480         mCalled = true;
1481         restoreChildFragmentState(savedInstanceState);
1482         if (mChildFragmentManager != null
1483                 && !mChildFragmentManager.isStateAtLeast(Fragment.CREATED)) {
1484             mChildFragmentManager.dispatchCreate();
1485         }
1486     }
1487 
1488     /**
1489      * Restore the state of the child FragmentManager. Called by either
1490      * {@link #onCreate(Bundle)} for non-retained instance fragments or by
1491      * {@link FragmentManagerImpl#moveToState(Fragment, int, int, int, boolean)}
1492      * for retained instance fragments.
1493      *
1494      * <p><strong>Postcondition:</strong> if there were child fragments to restore,
1495      * the child FragmentManager will be instantiated and brought to the {@link #CREATED} state.
1496      * </p>
1497      *
1498      * @param savedInstanceState the savedInstanceState potentially containing fragment info
1499      */
1500     void restoreChildFragmentState(@Nullable Bundle savedInstanceState) {
1501         if (savedInstanceState != null) {
1502             Parcelable p = savedInstanceState.getParcelable(
1503                     FragmentActivity.FRAGMENTS_TAG);
1504             if (p != null) {
1505                 if (mChildFragmentManager == null) {
1506                     instantiateChildFragmentManager();
1507                 }
1508                 mChildFragmentManager.restoreAllState(p, mChildNonConfig);
1509                 mChildNonConfig = null;
1510                 mChildFragmentManager.dispatchCreate();
1511             }
1512         }
1513     }
1514 
1515     /**
1516      * Called to have the fragment instantiate its user interface view.
1517      * This is optional, and non-graphical fragments can return null (which
1518      * is the default implementation).  This will be called between
1519      * {@link #onCreate(Bundle)} and {@link #onActivityCreated(Bundle)}.
1520      *
1521      * <p>If you return a View from here, you will later be called in
1522      * {@link #onDestroyView} when the view is being released.
1523      *
1524      * @param inflater The LayoutInflater object that can be used to inflate
1525      * any views in the fragment,
1526      * @param container If non-null, this is the parent view that the fragment's
1527      * UI should be attached to.  The fragment should not add the view itself,
1528      * but this can be used to generate the LayoutParams of the view.
1529      * @param savedInstanceState If non-null, this fragment is being re-constructed
1530      * from a previous saved state as given here.
1531      *
1532      * @return Return the View for the fragment's UI, or null.
1533      */
1534     @Nullable
1535     public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
1536             @Nullable Bundle savedInstanceState) {
1537         return null;
1538     }
1539 
1540     /**
1541      * Called immediately after {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}
1542      * has returned, but before any saved state has been restored in to the view.
1543      * This gives subclasses a chance to initialize themselves once
1544      * they know their view hierarchy has been completely created.  The fragment's
1545      * view hierarchy is not however attached to its parent at this point.
1546      * @param view The View returned by {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}.
1547      * @param savedInstanceState If non-null, this fragment is being re-constructed
1548      * from a previous saved state as given here.
1549      */
1550     public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
1551     }
1552 
1553     /**
1554      * Get the root view for the fragment's layout (the one returned by {@link #onCreateView}),
1555      * if provided.
1556      *
1557      * @return The fragment's root view, or null if it has no layout.
1558      */
1559     @Nullable
1560     public View getView() {
1561         return mView;
1562     }
1563 
1564     /**
1565      * Called when the fragment's activity has been created and this
1566      * fragment's view hierarchy instantiated.  It can be used to do final
1567      * initialization once these pieces are in place, such as retrieving
1568      * views or restoring state.  It is also useful for fragments that use
1569      * {@link #setRetainInstance(boolean)} to retain their instance,
1570      * as this callback tells the fragment when it is fully associated with
1571      * the new activity instance.  This is called after {@link #onCreateView}
1572      * and before {@link #onViewStateRestored(Bundle)}.
1573      *
1574      * @param savedInstanceState If the fragment is being re-created from
1575      * a previous saved state, this is the state.
1576      */
1577     @CallSuper
1578     public void onActivityCreated(@Nullable Bundle savedInstanceState) {
1579         mCalled = true;
1580     }
1581 
1582     /**
1583      * Called when all saved state has been restored into the view hierarchy
1584      * of the fragment.  This can be used to do initialization based on saved
1585      * state that you are letting the view hierarchy track itself, such as
1586      * whether check box widgets are currently checked.  This is called
1587      * after {@link #onActivityCreated(Bundle)} and before
1588      * {@link #onStart()}.
1589      *
1590      * @param savedInstanceState If the fragment is being re-created from
1591      * a previous saved state, this is the state.
1592      */
1593     @CallSuper
1594     public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
1595         mCalled = true;
1596         if (mView != null) {
1597             mViewLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
1598         }
1599     }
1600 
1601     /**
1602      * Called when the Fragment is visible to the user.  This is generally
1603      * tied to {@link Activity#onStart() Activity.onStart} of the containing
1604      * Activity's lifecycle.
1605      */
1606     @CallSuper
1607     public void onStart() {
1608         mCalled = true;
1609     }
1610 
1611     /**
1612      * Called when the fragment is visible to the user and actively running.
1613      * This is generally
1614      * tied to {@link Activity#onResume() Activity.onResume} of the containing
1615      * Activity's lifecycle.
1616      */
1617     @CallSuper
1618     public void onResume() {
1619         mCalled = true;
1620     }
1621 
1622     /**
1623      * Called to ask the fragment to save its current dynamic state, so it
1624      * can later be reconstructed in a new instance of its process is
1625      * restarted.  If a new instance of the fragment later needs to be
1626      * created, the data you place in the Bundle here will be available
1627      * in the Bundle given to {@link #onCreate(Bundle)},
1628      * {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}, and
1629      * {@link #onActivityCreated(Bundle)}.
1630      *
1631      * <p>This corresponds to {@link Activity#onSaveInstanceState(Bundle)
1632      * Activity.onSaveInstanceState(Bundle)} and most of the discussion there
1633      * applies here as well.  Note however: <em>this method may be called
1634      * at any time before {@link #onDestroy()}</em>.  There are many situations
1635      * where a fragment may be mostly torn down (such as when placed on the
1636      * back stack with no UI showing), but its state will not be saved until
1637      * its owning activity actually needs to save its state.
1638      *
1639      * @param outState Bundle in which to place your saved state.
1640      */
1641     public void onSaveInstanceState(@NonNull Bundle outState) {
1642     }
1643 
1644     /**
1645      * Called when the Fragment's activity changes from fullscreen mode to multi-window mode and
1646      * visa-versa. This is generally tied to {@link Activity#onMultiWindowModeChanged} of the
1647      * containing Activity.
1648      *
1649      * @param isInMultiWindowMode True if the activity is in multi-window mode.
1650      */
1651     public void onMultiWindowModeChanged(boolean isInMultiWindowMode) {
1652     }
1653 
1654     /**
1655      * Called by the system when the activity changes to and from picture-in-picture mode. This is
1656      * generally tied to {@link Activity#onPictureInPictureModeChanged} of the containing Activity.
1657      *
1658      * @param isInPictureInPictureMode True if the activity is in picture-in-picture mode.
1659      */
1660     public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
1661     }
1662 
1663     @Override
1664     @CallSuper
1665     public void onConfigurationChanged(Configuration newConfig) {
1666         mCalled = true;
1667     }
1668 
1669     /**
1670      * Called when the Fragment is no longer resumed.  This is generally
1671      * tied to {@link Activity#onPause() Activity.onPause} of the containing
1672      * Activity's lifecycle.
1673      */
1674     @CallSuper
1675     public void onPause() {
1676         mCalled = true;
1677     }
1678 
1679     /**
1680      * Called when the Fragment is no longer started.  This is generally
1681      * tied to {@link Activity#onStop() Activity.onStop} of the containing
1682      * Activity's lifecycle.
1683      */
1684     @CallSuper
1685     public void onStop() {
1686         mCalled = true;
1687     }
1688 
1689     @Override
1690     @CallSuper
1691     public void onLowMemory() {
1692         mCalled = true;
1693     }
1694 
1695     /**
1696      * Called when the view previously created by {@link #onCreateView} has
1697      * been detached from the fragment.  The next time the fragment needs
1698      * to be displayed, a new view will be created.  This is called
1699      * after {@link #onStop()} and before {@link #onDestroy()}.  It is called
1700      * <em>regardless</em> of whether {@link #onCreateView} returned a
1701      * non-null view.  Internally it is called after the view's state has
1702      * been saved but before it has been removed from its parent.
1703      */
1704     @CallSuper
1705     public void onDestroyView() {
1706         mCalled = true;
1707         if (mView != null) {
1708             mViewLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
1709         }
1710     }
1711 
1712     /**
1713      * Called when the fragment is no longer in use.  This is called
1714      * after {@link #onStop()} and before {@link #onDetach()}.
1715      */
1716     @CallSuper
1717     public void onDestroy() {
1718         mCalled = true;
1719         // Use mStateSaved instead of isStateSaved() since we're past onStop()
1720         if (mViewModelStore != null && !mHost.mFragmentManager.mStateSaved) {
1721             mViewModelStore.clear();
1722         }
1723     }
1724 
1725     /**
1726      * Called by the fragment manager once this fragment has been removed,
1727      * so that we don't have any left-over state if the application decides
1728      * to re-use the instance.  This only clears state that the framework
1729      * internally manages, not things the application sets.
1730      */
1731     void initState() {
1732         mIndex = -1;
1733         mWho = null;
1734         mAdded = false;
1735         mRemoving = false;
1736         mFromLayout = false;
1737         mInLayout = false;
1738         mRestored = false;
1739         mBackStackNesting = 0;
1740         mFragmentManager = null;
1741         mChildFragmentManager = null;
1742         mHost = null;
1743         mFragmentId = 0;
1744         mContainerId = 0;
1745         mTag = null;
1746         mHidden = false;
1747         mDetached = false;
1748         mRetaining = false;
1749     }
1750 
1751     /**
1752      * Called when the fragment is no longer attached to its activity.  This
1753      * is called after {@link #onDestroy()}.
1754      */
1755     @CallSuper
1756     public void onDetach() {
1757         mCalled = true;
1758     }
1759 
1760     /**
1761      * Initialize the contents of the Fragment host's standard options menu.  You
1762      * should place your menu items in to <var>menu</var>.  For this method
1763      * to be called, you must have first called {@link #setHasOptionsMenu}.  See
1764      * {@link Activity#onCreateOptionsMenu(Menu) Activity.onCreateOptionsMenu}
1765      * for more information.
1766      *
1767      * @param menu The options menu in which you place your items.
1768      *
1769      * @see #setHasOptionsMenu
1770      * @see #onPrepareOptionsMenu
1771      * @see #onOptionsItemSelected
1772      */
1773     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
1774     }
1775 
1776     /**
1777      * Prepare the Fragment host's standard options menu to be displayed.  This is
1778      * called right before the menu is shown, every time it is shown.  You can
1779      * use this method to efficiently enable/disable items or otherwise
1780      * dynamically modify the contents.  See
1781      * {@link Activity#onPrepareOptionsMenu(Menu) Activity.onPrepareOptionsMenu}
1782      * for more information.
1783      *
1784      * @param menu The options menu as last shown or first initialized by
1785      *             onCreateOptionsMenu().
1786      *
1787      * @see #setHasOptionsMenu
1788      * @see #onCreateOptionsMenu
1789      */
1790     public void onPrepareOptionsMenu(Menu menu) {
1791     }
1792 
1793     /**
1794      * Called when this fragment's option menu items are no longer being
1795      * included in the overall options menu.  Receiving this call means that
1796      * the menu needed to be rebuilt, but this fragment's items were not
1797      * included in the newly built menu (its {@link #onCreateOptionsMenu(Menu, MenuInflater)}
1798      * was not called).
1799      */
1800     public void onDestroyOptionsMenu() {
1801     }
1802 
1803     /**
1804      * This hook is called whenever an item in your options menu is selected.
1805      * The default implementation simply returns false to have the normal
1806      * processing happen (calling the item's Runnable or sending a message to
1807      * its Handler as appropriate).  You can use this method for any items
1808      * for which you would like to do processing without those other
1809      * facilities.
1810      *
1811      * <p>Derived classes should call through to the base class for it to
1812      * perform the default menu handling.
1813      *
1814      * @param item The menu item that was selected.
1815      *
1816      * @return boolean Return false to allow normal menu processing to
1817      *         proceed, true to consume it here.
1818      *
1819      * @see #onCreateOptionsMenu
1820      */
1821     public boolean onOptionsItemSelected(MenuItem item) {
1822         return false;
1823     }
1824 
1825     /**
1826      * This hook is called whenever the options menu is being closed (either by the user canceling
1827      * the menu with the back/menu button, or when an item is selected).
1828      *
1829      * @param menu The options menu as last shown or first initialized by
1830      *             onCreateOptionsMenu().
1831      */
1832     public void onOptionsMenuClosed(Menu menu) {
1833     }
1834 
1835     /**
1836      * Called when a context menu for the {@code view} is about to be shown.
1837      * Unlike {@link #onCreateOptionsMenu}, this will be called every
1838      * time the context menu is about to be shown and should be populated for
1839      * the view (or item inside the view for {@link AdapterView} subclasses,
1840      * this can be found in the {@code menuInfo})).
1841      * <p>
1842      * Use {@link #onContextItemSelected(android.view.MenuItem)} to know when an
1843      * item has been selected.
1844      * <p>
1845      * The default implementation calls up to
1846      * {@link Activity#onCreateContextMenu Activity.onCreateContextMenu}, though
1847      * you can not call this implementation if you don't want that behavior.
1848      * <p>
1849      * It is not safe to hold onto the context menu after this method returns.
1850      * {@inheritDoc}
1851      */
1852     @Override
1853     public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
1854         getActivity().onCreateContextMenu(menu, v, menuInfo);
1855     }
1856 
1857     /**
1858      * Registers a context menu to be shown for the given view (multiple views
1859      * can show the context menu). This method will set the
1860      * {@link OnCreateContextMenuListener} on the view to this fragment, so
1861      * {@link #onCreateContextMenu(ContextMenu, View, ContextMenuInfo)} will be
1862      * called when it is time to show the context menu.
1863      *
1864      * @see #unregisterForContextMenu(View)
1865      * @param view The view that should show a context menu.
1866      */
1867     public void registerForContextMenu(View view) {
1868         view.setOnCreateContextMenuListener(this);
1869     }
1870 
1871     /**
1872      * Prevents a context menu to be shown for the given view. This method will
1873      * remove the {@link OnCreateContextMenuListener} on the view.
1874      *
1875      * @see #registerForContextMenu(View)
1876      * @param view The view that should stop showing a context menu.
1877      */
1878     public void unregisterForContextMenu(View view) {
1879         view.setOnCreateContextMenuListener(null);
1880     }
1881 
1882     /**
1883      * This hook is called whenever an item in a context menu is selected. The
1884      * default implementation simply returns false to have the normal processing
1885      * happen (calling the item's Runnable or sending a message to its Handler
1886      * as appropriate). You can use this method for any items for which you
1887      * would like to do processing without those other facilities.
1888      * <p>
1889      * Use {@link MenuItem#getMenuInfo()} to get extra information set by the
1890      * View that added this menu item.
1891      * <p>
1892      * Derived classes should call through to the base class for it to perform
1893      * the default menu handling.
1894      *
1895      * @param item The context menu item that was selected.
1896      * @return boolean Return false to allow normal context menu processing to
1897      *         proceed, true to consume it here.
1898      */
1899     public boolean onContextItemSelected(MenuItem item) {
1900         return false;
1901     }
1902 
1903     /**
1904      * When custom transitions are used with Fragments, the enter transition callback
1905      * is called when this Fragment is attached or detached when not popping the back stack.
1906      *
1907      * @param callback Used to manipulate the shared element transitions on this Fragment
1908      *                 when added not as a pop from the back stack.
1909      */
1910     public void setEnterSharedElementCallback(SharedElementCallback callback) {
1911         ensureAnimationInfo().mEnterTransitionCallback = callback;
1912     }
1913 
1914     /**
1915      * When custom transitions are used with Fragments, the exit transition callback
1916      * is called when this Fragment is attached or detached when popping the back stack.
1917      *
1918      * @param callback Used to manipulate the shared element transitions on this Fragment
1919      *                 when added as a pop from the back stack.
1920      */
1921     public void setExitSharedElementCallback(SharedElementCallback callback) {
1922         ensureAnimationInfo().mExitTransitionCallback = callback;
1923     }
1924 
1925     /**
1926      * Sets the Transition that will be used to move Views into the initial scene. The entering
1927      * Views will be those that are regular Views or ViewGroups that have
1928      * {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend
1929      * {@link android.transition.Visibility} as entering is governed by changing visibility from
1930      * {@link View#INVISIBLE} to {@link View#VISIBLE}. If <code>transition</code> is null,
1931      * entering Views will remain unaffected.
1932      *
1933      * @param transition The Transition to use to move Views into the initial Scene.
1934      */
1935     public void setEnterTransition(@Nullable Object transition) {
1936         ensureAnimationInfo().mEnterTransition = transition;
1937     }
1938 
1939     /**
1940      * Returns the Transition that will be used to move Views into the initial scene. The entering
1941      * Views will be those that are regular Views or ViewGroups that have
1942      * {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend
1943      * {@link android.transition.Visibility} as entering is governed by changing visibility from
1944      * {@link View#INVISIBLE} to {@link View#VISIBLE}.
1945      *
1946      * @return the Transition to use to move Views into the initial Scene.
1947      */
1948     @Nullable
1949     public Object getEnterTransition() {
1950         if (mAnimationInfo == null) {
1951             return null;
1952         }
1953         return mAnimationInfo.mEnterTransition;
1954     }
1955 
1956     /**
1957      * Sets the Transition that will be used to move Views out of the scene when the Fragment is
1958      * preparing to be removed, hidden, or detached because of popping the back stack. The exiting
1959      * Views will be those that are regular Views or ViewGroups that have
1960      * {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend
1961      * {@link android.transition.Visibility} as entering is governed by changing visibility from
1962      * {@link View#VISIBLE} to {@link View#INVISIBLE}. If <code>transition</code> is null,
1963      * entering Views will remain unaffected. If nothing is set, the default will be to
1964      * use the same value as set in {@link #setEnterTransition(Object)}.
1965      *
1966      * @param transition The Transition to use to move Views out of the Scene when the Fragment
1967      *         is preparing to close. <code>transition</code> must be an
1968      *         {@link android.transition.Transition android.transition.Transition} or
1969      *         {@link androidx.transition.Transition androidx.transition.Transition}.
1970      */
1971     public void setReturnTransition(@Nullable Object transition) {
1972         ensureAnimationInfo().mReturnTransition = transition;
1973     }
1974 
1975     /**
1976      * Returns the Transition that will be used to move Views out of the scene when the Fragment is
1977      * preparing to be removed, hidden, or detached because of popping the back stack. The exiting
1978      * Views will be those that are regular Views or ViewGroups that have
1979      * {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend
1980      * {@link android.transition.Visibility} as entering is governed by changing visibility from
1981      * {@link View#VISIBLE} to {@link View#INVISIBLE}. If <code>transition</code> is null,
1982      * entering Views will remain unaffected.
1983      *
1984      * @return the Transition to use to move Views out of the Scene when the Fragment
1985      *         is preparing to close.
1986      */
1987     @Nullable
1988     public Object getReturnTransition() {
1989         if (mAnimationInfo == null) {
1990             return null;
1991         }
1992         return mAnimationInfo.mReturnTransition == USE_DEFAULT_TRANSITION ? getEnterTransition()
1993                 : mAnimationInfo.mReturnTransition;
1994     }
1995 
1996     /**
1997      * Sets the Transition that will be used to move Views out of the scene when the
1998      * fragment is removed, hidden, or detached when not popping the back stack.
1999      * The exiting Views will be those that are regular Views or ViewGroups that
2000      * have {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend
2001      * {@link android.transition.Visibility} as exiting is governed by changing visibility
2002      * from {@link View#VISIBLE} to {@link View#INVISIBLE}. If transition is null, the views will
2003      * remain unaffected.
2004      *
2005      * @param transition The Transition to use to move Views out of the Scene when the Fragment
2006      *          is being closed not due to popping the back stack. <code>transition</code>
2007      *          must be an
2008      *          {@link android.transition.Transition android.transition.Transition} or
2009      *          {@link androidx.transition.Transition androidx.transition.Transition}.
2010      */
2011     public void setExitTransition(@Nullable Object transition) {
2012         ensureAnimationInfo().mExitTransition = transition;
2013     }
2014 
2015     /**
2016      * Returns the Transition that will be used to move Views out of the scene when the
2017      * fragment is removed, hidden, or detached when not popping the back stack.
2018      * The exiting Views will be those that are regular Views or ViewGroups that
2019      * have {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend
2020      * {@link android.transition.Visibility} as exiting is governed by changing visibility
2021      * from {@link View#VISIBLE} to {@link View#INVISIBLE}. If transition is null, the views will
2022      * remain unaffected.
2023      *
2024      * @return the Transition to use to move Views out of the Scene when the Fragment
2025      *         is being closed not due to popping the back stack.
2026      */
2027     @Nullable
2028     public Object getExitTransition() {
2029         if (mAnimationInfo == null) {
2030             return null;
2031         }
2032         return mAnimationInfo.mExitTransition;
2033     }
2034 
2035     /**
2036      * Sets the Transition that will be used to move Views in to the scene when returning due
2037      * to popping a back stack. The entering Views will be those that are regular Views
2038      * or ViewGroups that have {@link ViewGroup#isTransitionGroup} return true. Typical Transitions
2039      * will extend {@link android.transition.Visibility} as exiting is governed by changing
2040      * visibility from {@link View#VISIBLE} to {@link View#INVISIBLE}. If transition is null,
2041      * the views will remain unaffected. If nothing is set, the default will be to use the same
2042      * transition as {@link #setExitTransition(Object)}.
2043      *
2044      * @param transition The Transition to use to move Views into the scene when reentering from a
2045      *          previously-started Activity. <code>transition</code>
2046      *          must be an
2047      *          {@link android.transition.Transition android.transition.Transition} or
2048      *          {@link androidx.transition.Transition androidx.transition.Transition}.
2049      */
2050     public void setReenterTransition(@Nullable Object transition) {
2051         ensureAnimationInfo().mReenterTransition = transition;
2052     }
2053 
2054     /**
2055      * Returns the Transition that will be used to move Views in to the scene when returning due
2056      * to popping a back stack. The entering Views will be those that are regular Views
2057      * or ViewGroups that have {@link ViewGroup#isTransitionGroup} return true. Typical Transitions
2058      * will extend {@link android.transition.Visibility} as exiting is governed by changing
2059      * visibility from {@link View#VISIBLE} to {@link View#INVISIBLE}. If transition is null,
2060      * the views will remain unaffected. If nothing is set, the default will be to use the same
2061      * transition as {@link #setExitTransition(Object)}.
2062      *
2063      * @return the Transition to use to move Views into the scene when reentering from a
2064      *                   previously-started Activity.
2065      */
2066     public Object getReenterTransition() {
2067         if (mAnimationInfo == null) {
2068             return null;
2069         }
2070         return mAnimationInfo.mReenterTransition == USE_DEFAULT_TRANSITION ? getExitTransition()
2071                 : mAnimationInfo.mReenterTransition;
2072     }
2073 
2074     /**
2075      * Sets the Transition that will be used for shared elements transferred into the content
2076      * Scene. Typical Transitions will affect size and location, such as
2077      * {@link android.transition.ChangeBounds}. A null
2078      * value will cause transferred shared elements to blink to the final position.
2079      *
2080      * @param transition The Transition to use for shared elements transferred into the content
2081      *          Scene.  <code>transition</code> must be an
2082      *          {@link android.transition.Transition android.transition.Transition} or
2083      *          {@link androidx.transition.Transition androidx.transition.Transition}.
2084      */
2085     public void setSharedElementEnterTransition(@Nullable Object transition) {
2086         ensureAnimationInfo().mSharedElementEnterTransition = transition;
2087     }
2088 
2089     /**
2090      * Returns the Transition that will be used for shared elements transferred into the content
2091      * Scene. Typical Transitions will affect size and location, such as
2092      * {@link android.transition.ChangeBounds}. A null
2093      * value will cause transferred shared elements to blink to the final position.
2094      *
2095      * @return The Transition to use for shared elements transferred into the content
2096      *                   Scene.
2097      */
2098     @Nullable
2099     public Object getSharedElementEnterTransition() {
2100         if (mAnimationInfo == null) {
2101             return null;
2102         }
2103         return mAnimationInfo.mSharedElementEnterTransition;
2104     }
2105 
2106     /**
2107      * Sets the Transition that will be used for shared elements transferred back during a
2108      * pop of the back stack. This Transition acts in the leaving Fragment.
2109      * Typical Transitions will affect size and location, such as
2110      * {@link android.transition.ChangeBounds}. A null
2111      * value will cause transferred shared elements to blink to the final position.
2112      * If no value is set, the default will be to use the same value as
2113      * {@link #setSharedElementEnterTransition(Object)}.
2114      *
2115      * @param transition The Transition to use for shared elements transferred out of the content
2116      *          Scene. <code>transition</code> must be an
2117      *          {@link android.transition.Transition android.transition.Transition} or
2118      *          {@link androidx.transition.Transition androidx.transition.Transition}.
2119      */
2120     public void setSharedElementReturnTransition(@Nullable Object transition) {
2121         ensureAnimationInfo().mSharedElementReturnTransition = transition;
2122     }
2123 
2124     /**
2125      * Return the Transition that will be used for shared elements transferred back during a
2126      * pop of the back stack. This Transition acts in the leaving Fragment.
2127      * Typical Transitions will affect size and location, such as
2128      * {@link android.transition.ChangeBounds}. A null
2129      * value will cause transferred shared elements to blink to the final position.
2130      * If no value is set, the default will be to use the same value as
2131      * {@link #setSharedElementEnterTransition(Object)}.
2132      *
2133      * @return The Transition to use for shared elements transferred out of the content
2134      *                   Scene.
2135      */
2136     @Nullable
2137     public Object getSharedElementReturnTransition() {
2138         if (mAnimationInfo == null) {
2139             return null;
2140         }
2141         return mAnimationInfo.mSharedElementReturnTransition == USE_DEFAULT_TRANSITION
2142                 ? getSharedElementEnterTransition()
2143                 : mAnimationInfo.mSharedElementReturnTransition;
2144     }
2145 
2146     /**
2147      * Sets whether the the exit transition and enter transition overlap or not.
2148      * When true, the enter transition will start as soon as possible. When false, the
2149      * enter transition will wait until the exit transition completes before starting.
2150      *
2151      * @param allow true to start the enter transition when possible or false to
2152      *              wait until the exiting transition completes.
2153      */
2154     public void setAllowEnterTransitionOverlap(boolean allow) {
2155         ensureAnimationInfo().mAllowEnterTransitionOverlap = allow;
2156     }
2157 
2158     /**
2159      * Returns whether the the exit transition and enter transition overlap or not.
2160      * When true, the enter transition will start as soon as possible. When false, the
2161      * enter transition will wait until the exit transition completes before starting.
2162      *
2163      * @return true when the enter transition should start as soon as possible or false to
2164      * when it should wait until the exiting transition completes.
2165      */
2166     public boolean getAllowEnterTransitionOverlap() {
2167         return (mAnimationInfo == null || mAnimationInfo.mAllowEnterTransitionOverlap == null)
2168                 ? true : mAnimationInfo.mAllowEnterTransitionOverlap;
2169     }
2170 
2171     /**
2172      * Sets whether the the return transition and reenter transition overlap or not.
2173      * When true, the reenter transition will start as soon as possible. When false, the
2174      * reenter transition will wait until the return transition completes before starting.
2175      *
2176      * @param allow true to start the reenter transition when possible or false to wait until the
2177      *              return transition completes.
2178      */
2179     public void setAllowReturnTransitionOverlap(boolean allow) {
2180         ensureAnimationInfo().mAllowReturnTransitionOverlap = allow;
2181     }
2182 
2183     /**
2184      * Returns whether the the return transition and reenter transition overlap or not.
2185      * When true, the reenter transition will start as soon as possible. When false, the
2186      * reenter transition will wait until the return transition completes before starting.
2187      *
2188      * @return true to start the reenter transition when possible or false to wait until the
2189      *         return transition completes.
2190      */
2191     public boolean getAllowReturnTransitionOverlap() {
2192         return (mAnimationInfo == null || mAnimationInfo.mAllowReturnTransitionOverlap == null)
2193                 ? true : mAnimationInfo.mAllowReturnTransitionOverlap;
2194     }
2195 
2196     /**
2197      * Postpone the entering Fragment transition until {@link #startPostponedEnterTransition()}
2198      * or {@link FragmentManager#executePendingTransactions()} has been called.
2199      * <p>
2200      * This method gives the Fragment the ability to delay Fragment animations
2201      * until all data is loaded. Until then, the added, shown, and
2202      * attached Fragments will be INVISIBLE and removed, hidden, and detached Fragments won't
2203      * be have their Views removed. The transaction runs when all postponed added Fragments in the
2204      * transaction have called {@link #startPostponedEnterTransition()}.
2205      * <p>
2206      * This method should be called before being added to the FragmentTransaction or
2207      * in {@link #onCreate(Bundle), {@link #onAttach(Context)}, or
2208      * {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}}.
2209      * {@link #startPostponedEnterTransition()} must be called to allow the Fragment to
2210      * start the transitions.
2211      * <p>
2212      * When a FragmentTransaction is started that may affect a postponed FragmentTransaction,
2213      * based on which containers are in their operations, the postponed FragmentTransaction
2214      * will have its start triggered. The early triggering may result in faulty or nonexistent
2215      * animations in the postponed transaction. FragmentTransactions that operate only on
2216      * independent containers will not interfere with each other's postponement.
2217      * <p>
2218      * Calling postponeEnterTransition on Fragments with a null View will not postpone the
2219      * transition. Likewise, postponement only works if
2220      * {@link FragmentTransaction#setReorderingAllowed(boolean) FragmentTransaction reordering} is
2221      * enabled.
2222      *
2223      * @see Activity#postponeEnterTransition()
2224      * @see FragmentTransaction#setReorderingAllowed(boolean)
2225      */
2226     public void postponeEnterTransition() {
2227         ensureAnimationInfo().mEnterTransitionPostponed = true;
2228     }
2229 
2230     /**
2231      * Begin postponed transitions after {@link #postponeEnterTransition()} was called.
2232      * If postponeEnterTransition() was called, you must call startPostponedEnterTransition()
2233      * or {@link FragmentManager#executePendingTransactions()} to complete the FragmentTransaction.
2234      * If postponement was interrupted with {@link FragmentManager#executePendingTransactions()},
2235      * before {@code startPostponedEnterTransition()}, animations may not run or may execute
2236      * improperly.
2237      *
2238      * @see Activity#startPostponedEnterTransition()
2239      */
2240     public void startPostponedEnterTransition() {
2241         if (mFragmentManager == null || mFragmentManager.mHost == null) {
2242             ensureAnimationInfo().mEnterTransitionPostponed = false;
2243         } else if (Looper.myLooper() != mFragmentManager.mHost.getHandler().getLooper()) {
2244             mFragmentManager.mHost.getHandler().postAtFrontOfQueue(new Runnable() {
2245                 @Override
2246                 public void run() {
2247                     callStartTransitionListener();
2248                 }
2249             });
2250         } else {
2251             callStartTransitionListener();
2252         }
2253     }
2254 
2255     /**
2256      * Calls the start transition listener. This must be called on the UI thread.
2257      */
2258     private void callStartTransitionListener() {
2259         final OnStartEnterTransitionListener listener;
2260         if (mAnimationInfo == null) {
2261             listener = null;
2262         } else {
2263             mAnimationInfo.mEnterTransitionPostponed = false;
2264             listener = mAnimationInfo.mStartEnterTransitionListener;
2265             mAnimationInfo.mStartEnterTransitionListener = null;
2266         }
2267         if (listener != null) {
2268             listener.onStartEnterTransition();
2269         }
2270     }
2271 
2272     /**
2273      * Print the Fragments's state into the given stream.
2274      *
2275      * @param prefix Text to print at the front of each line.
2276      * @param fd The raw file descriptor that the dump is being sent to.
2277      * @param writer The PrintWriter to which you should dump your state.  This will be
2278      * closed for you after you return.
2279      * @param args additional arguments to the dump request.
2280      */
2281     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
2282         writer.print(prefix); writer.print("mFragmentId=#");
2283                 writer.print(Integer.toHexString(mFragmentId));
2284                 writer.print(" mContainerId=#");
2285                 writer.print(Integer.toHexString(mContainerId));
2286                 writer.print(" mTag="); writer.println(mTag);
2287         writer.print(prefix); writer.print("mState="); writer.print(mState);
2288                 writer.print(" mIndex="); writer.print(mIndex);
2289                 writer.print(" mWho="); writer.print(mWho);
2290                 writer.print(" mBackStackNesting="); writer.println(mBackStackNesting);
2291         writer.print(prefix); writer.print("mAdded="); writer.print(mAdded);
2292                 writer.print(" mRemoving="); writer.print(mRemoving);
2293                 writer.print(" mFromLayout="); writer.print(mFromLayout);
2294                 writer.print(" mInLayout="); writer.println(mInLayout);
2295         writer.print(prefix); writer.print("mHidden="); writer.print(mHidden);
2296                 writer.print(" mDetached="); writer.print(mDetached);
2297                 writer.print(" mMenuVisible="); writer.print(mMenuVisible);
2298                 writer.print(" mHasMenu="); writer.println(mHasMenu);
2299         writer.print(prefix); writer.print("mRetainInstance="); writer.print(mRetainInstance);
2300                 writer.print(" mRetaining="); writer.print(mRetaining);
2301                 writer.print(" mUserVisibleHint="); writer.println(mUserVisibleHint);
2302         if (mFragmentManager != null) {
2303             writer.print(prefix); writer.print("mFragmentManager=");
2304                     writer.println(mFragmentManager);
2305         }
2306         if (mHost != null) {
2307             writer.print(prefix); writer.print("mHost=");
2308                     writer.println(mHost);
2309         }
2310         if (mParentFragment != null) {
2311             writer.print(prefix); writer.print("mParentFragment=");
2312                     writer.println(mParentFragment);
2313         }
2314         if (mArguments != null) {
2315             writer.print(prefix); writer.print("mArguments="); writer.println(mArguments);
2316         }
2317         if (mSavedFragmentState != null) {
2318             writer.print(prefix); writer.print("mSavedFragmentState=");
2319                     writer.println(mSavedFragmentState);
2320         }
2321         if (mSavedViewState != null) {
2322             writer.print(prefix); writer.print("mSavedViewState=");
2323                     writer.println(mSavedViewState);
2324         }
2325         if (mTarget != null) {
2326             writer.print(prefix); writer.print("mTarget="); writer.print(mTarget);
2327                     writer.print(" mTargetRequestCode=");
2328                     writer.println(mTargetRequestCode);
2329         }
2330         if (getNextAnim() != 0) {
2331             writer.print(prefix); writer.print("mNextAnim="); writer.println(getNextAnim());
2332         }
2333         if (mContainer != null) {
2334             writer.print(prefix); writer.print("mContainer="); writer.println(mContainer);
2335         }
2336         if (mView != null) {
2337             writer.print(prefix); writer.print("mView="); writer.println(mView);
2338         }
2339         if (mInnerView != null) {
2340             writer.print(prefix); writer.print("mInnerView="); writer.println(mView);
2341         }
2342         if (getAnimatingAway() != null) {
2343             writer.print(prefix);
2344             writer.print("mAnimatingAway=");
2345             writer.println(getAnimatingAway());
2346             writer.print(prefix);
2347             writer.print("mStateAfterAnimating=");
2348             writer.println(getStateAfterAnimating());
2349         }
2350         LoaderManager.getInstance(this).dump(prefix, fd, writer, args);
2351         if (mChildFragmentManager != null) {
2352             writer.print(prefix); writer.println("Child " + mChildFragmentManager + ":");
2353             mChildFragmentManager.dump(prefix + "  ", fd, writer, args);
2354         }
2355     }
2356 
2357     Fragment findFragmentByWho(String who) {
2358         if (who.equals(mWho)) {
2359             return this;
2360         }
2361         if (mChildFragmentManager != null) {
2362             return mChildFragmentManager.findFragmentByWho(who);
2363         }
2364         return null;
2365     }
2366 
2367     void instantiateChildFragmentManager() {
2368         if (mHost == null) {
2369             throw new IllegalStateException("Fragment has not been attached yet.");
2370         }
2371         mChildFragmentManager = new FragmentManagerImpl();
2372         mChildFragmentManager.attachController(mHost, new FragmentContainer() {
2373             @Override
2374             @Nullable
2375             public View onFindViewById(int id) {
2376                 if (mView == null) {
2377                     throw new IllegalStateException("Fragment does not have a view");
2378                 }
2379                 return mView.findViewById(id);
2380             }
2381 
2382             @Override
2383             public boolean onHasView() {
2384                 return (mView != null);
2385             }
2386 
2387             @Override
2388             public Fragment instantiate(Context context, String className, Bundle arguments) {
2389                 return mHost.instantiate(context, className, arguments);
2390             }
2391         }, this);
2392     }
2393 
2394     void performCreate(Bundle savedInstanceState) {
2395         if (mChildFragmentManager != null) {
2396             mChildFragmentManager.noteStateNotSaved();
2397         }
2398         mState = CREATED;
2399         mCalled = false;
2400         onCreate(savedInstanceState);
2401         mIsCreated = true;
2402         if (!mCalled) {
2403             throw new SuperNotCalledException("Fragment " + this
2404                     + " did not call through to super.onCreate()");
2405         }
2406         mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
2407     }
2408 
2409     void performCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
2410             @Nullable Bundle savedInstanceState) {
2411         if (mChildFragmentManager != null) {
2412             mChildFragmentManager.noteStateNotSaved();
2413         }
2414         mPerformedCreateView = true;
2415         mViewLifecycleOwner = new LifecycleOwner() {
2416             @Override
2417             public Lifecycle getLifecycle() {
2418                 if (mViewLifecycleRegistry == null) {
2419                     mViewLifecycleRegistry = new LifecycleRegistry(mViewLifecycleOwner);
2420                 }
2421                 return mViewLifecycleRegistry;
2422             }
2423         };
2424         mViewLifecycleRegistry = null;
2425         mView = onCreateView(inflater, container, savedInstanceState);
2426         if (mView != null) {
2427             // Initialize the LifecycleRegistry if needed
2428             mViewLifecycleOwner.getLifecycle();
2429             // Then inform any Observers of the new LifecycleOwner
2430             mViewLifecycleOwnerLiveData.setValue(mViewLifecycleOwner);
2431         } else {
2432             if (mViewLifecycleRegistry != null) {
2433                 throw new IllegalStateException("Called getViewLifecycleOwner() but "
2434                         + "onCreateView() returned null");
2435             }
2436             mViewLifecycleOwner = null;
2437         }
2438     }
2439 
2440     void performActivityCreated(Bundle savedInstanceState) {
2441         if (mChildFragmentManager != null) {
2442             mChildFragmentManager.noteStateNotSaved();
2443         }
2444         mState = ACTIVITY_CREATED;
2445         mCalled = false;
2446         onActivityCreated(savedInstanceState);
2447         if (!mCalled) {
2448             throw new SuperNotCalledException("Fragment " + this
2449                     + " did not call through to super.onActivityCreated()");
2450         }
2451         if (mChildFragmentManager != null) {
2452             mChildFragmentManager.dispatchActivityCreated();
2453         }
2454     }
2455 
2456     void performStart() {
2457         if (mChildFragmentManager != null) {
2458             mChildFragmentManager.noteStateNotSaved();
2459             mChildFragmentManager.execPendingActions();
2460         }
2461         mState = STARTED;
2462         mCalled = false;
2463         onStart();
2464         if (!mCalled) {
2465             throw new SuperNotCalledException("Fragment " + this
2466                     + " did not call through to super.onStart()");
2467         }
2468         if (mChildFragmentManager != null) {
2469             mChildFragmentManager.dispatchStart();
2470         }
2471         mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
2472         if (mView != null) {
2473             mViewLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
2474         }
2475     }
2476 
2477     void performResume() {
2478         if (mChildFragmentManager != null) {
2479             mChildFragmentManager.noteStateNotSaved();
2480             mChildFragmentManager.execPendingActions();
2481         }
2482         mState = RESUMED;
2483         mCalled = false;
2484         onResume();
2485         if (!mCalled) {
2486             throw new SuperNotCalledException("Fragment " + this
2487                     + " did not call through to super.onResume()");
2488         }
2489         if (mChildFragmentManager != null) {
2490             mChildFragmentManager.dispatchResume();
2491             mChildFragmentManager.execPendingActions();
2492         }
2493         mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
2494         if (mView != null) {
2495             mViewLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
2496         }
2497     }
2498 
2499     void noteStateNotSaved() {
2500         if (mChildFragmentManager != null) {
2501             mChildFragmentManager.noteStateNotSaved();
2502         }
2503     }
2504 
2505     void performMultiWindowModeChanged(boolean isInMultiWindowMode) {
2506         onMultiWindowModeChanged(isInMultiWindowMode);
2507         if (mChildFragmentManager != null) {
2508             mChildFragmentManager.dispatchMultiWindowModeChanged(isInMultiWindowMode);
2509         }
2510     }
2511 
2512     void performPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
2513         onPictureInPictureModeChanged(isInPictureInPictureMode);
2514         if (mChildFragmentManager != null) {
2515             mChildFragmentManager.dispatchPictureInPictureModeChanged(isInPictureInPictureMode);
2516         }
2517     }
2518 
2519     void performConfigurationChanged(Configuration newConfig) {
2520         onConfigurationChanged(newConfig);
2521         if (mChildFragmentManager != null) {
2522             mChildFragmentManager.dispatchConfigurationChanged(newConfig);
2523         }
2524     }
2525 
2526     void performLowMemory() {
2527         onLowMemory();
2528         if (mChildFragmentManager != null) {
2529             mChildFragmentManager.dispatchLowMemory();
2530         }
2531     }
2532 
2533     /*
2534     void performTrimMemory(int level) {
2535         onTrimMemory(level);
2536         if (mChildFragmentManager != null) {
2537             mChildFragmentManager.dispatchTrimMemory(level);
2538         }
2539     }
2540     */
2541 
2542     boolean performCreateOptionsMenu(Menu menu, MenuInflater inflater) {
2543         boolean show = false;
2544         if (!mHidden) {
2545             if (mHasMenu && mMenuVisible) {
2546                 show = true;
2547                 onCreateOptionsMenu(menu, inflater);
2548             }
2549             if (mChildFragmentManager != null) {
2550                 show |= mChildFragmentManager.dispatchCreateOptionsMenu(menu, inflater);
2551             }
2552         }
2553         return show;
2554     }
2555 
2556     boolean performPrepareOptionsMenu(Menu menu) {
2557         boolean show = false;
2558         if (!mHidden) {
2559             if (mHasMenu && mMenuVisible) {
2560                 show = true;
2561                 onPrepareOptionsMenu(menu);
2562             }
2563             if (mChildFragmentManager != null) {
2564                 show |= mChildFragmentManager.dispatchPrepareOptionsMenu(menu);
2565             }
2566         }
2567         return show;
2568     }
2569 
2570     boolean performOptionsItemSelected(MenuItem item) {
2571         if (!mHidden) {
2572             if (mHasMenu && mMenuVisible) {
2573                 if (onOptionsItemSelected(item)) {
2574                     return true;
2575                 }
2576             }
2577             if (mChildFragmentManager != null) {
2578                 if (mChildFragmentManager.dispatchOptionsItemSelected(item)) {
2579                     return true;
2580                 }
2581             }
2582         }
2583         return false;
2584     }
2585 
2586     boolean performContextItemSelected(MenuItem item) {
2587         if (!mHidden) {
2588             if (onContextItemSelected(item)) {
2589                 return true;
2590             }
2591             if (mChildFragmentManager != null) {
2592                 if (mChildFragmentManager.dispatchContextItemSelected(item)) {
2593                     return true;
2594                 }
2595             }
2596         }
2597         return false;
2598     }
2599 
2600     void performOptionsMenuClosed(Menu menu) {
2601         if (!mHidden) {
2602             if (mHasMenu && mMenuVisible) {
2603                 onOptionsMenuClosed(menu);
2604             }
2605             if (mChildFragmentManager != null) {
2606                 mChildFragmentManager.dispatchOptionsMenuClosed(menu);
2607             }
2608         }
2609     }
2610 
2611     void performSaveInstanceState(Bundle outState) {
2612         onSaveInstanceState(outState);
2613         if (mChildFragmentManager != null) {
2614             Parcelable p = mChildFragmentManager.saveAllState();
2615             if (p != null) {
2616                 outState.putParcelable(FragmentActivity.FRAGMENTS_TAG, p);
2617             }
2618         }
2619     }
2620 
2621     void performPause() {
2622         if (mView != null) {
2623             mViewLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
2624         }
2625         mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
2626         if (mChildFragmentManager != null) {
2627             mChildFragmentManager.dispatchPause();
2628         }
2629         mState = STARTED;
2630         mCalled = false;
2631         onPause();
2632         if (!mCalled) {
2633             throw new SuperNotCalledException("Fragment " + this
2634                     + " did not call through to super.onPause()");
2635         }
2636     }
2637 
2638     void performStop() {
2639         mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
2640         if (mChildFragmentManager != null) {
2641             mChildFragmentManager.dispatchStop();
2642         }
2643         mState = ACTIVITY_CREATED;
2644         mCalled = false;
2645         onStop();
2646         if (!mCalled) {
2647             throw new SuperNotCalledException("Fragment " + this
2648                     + " did not call through to super.onStop()");
2649         }
2650     }
2651 
2652     void performDestroyView() {
2653         if (mChildFragmentManager != null) {
2654             mChildFragmentManager.dispatchDestroyView();
2655         }
2656         mState = CREATED;
2657         mCalled = false;
2658         onDestroyView();
2659         if (!mCalled) {
2660             throw new SuperNotCalledException("Fragment " + this
2661                     + " did not call through to super.onDestroyView()");
2662         }
2663         // Handles the detach/reattach case where the view hierarchy
2664         // is destroyed and recreated and an additional call to
2665         // onLoadFinished may be needed to ensure the new view
2666         // hierarchy is populated from data from the Loaders
2667         LoaderManager.getInstance(this).markForRedelivery();
2668         mPerformedCreateView = false;
2669     }
2670 
2671     void performDestroy() {
2672         mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
2673         if (mChildFragmentManager != null) {
2674             mChildFragmentManager.dispatchDestroy();
2675         }
2676         mState = INITIALIZING;
2677         mCalled = false;
2678         mIsCreated = false;
2679         onDestroy();
2680         if (!mCalled) {
2681             throw new SuperNotCalledException("Fragment " + this
2682                     + " did not call through to super.onDestroy()");
2683         }
2684         mChildFragmentManager = null;
2685     }
2686 
2687     void performDetach() {
2688         mCalled = false;
2689         onDetach();
2690         mLayoutInflater = null;
2691         if (!mCalled) {
2692             throw new SuperNotCalledException("Fragment " + this
2693                     + " did not call through to super.onDetach()");
2694         }
2695 
2696         // Destroy the child FragmentManager if we still have it here.
2697         // We won't unless we're retaining our instance and if we do,
2698         // our child FragmentManager instance state will have already been saved.
2699         if (mChildFragmentManager != null) {
2700             if (!mRetaining) {
2701                 throw new IllegalStateException("Child FragmentManager of " + this + " was not "
2702                         + " destroyed and this fragment is not retaining instance");
2703             }
2704             mChildFragmentManager.dispatchDestroy();
2705             mChildFragmentManager = null;
2706         }
2707     }
2708 
2709     void setOnStartEnterTransitionListener(OnStartEnterTransitionListener listener) {
2710         ensureAnimationInfo();
2711         if (listener == mAnimationInfo.mStartEnterTransitionListener) {
2712             return;
2713         }
2714         if (listener != null && mAnimationInfo.mStartEnterTransitionListener != null) {
2715             throw new IllegalStateException("Trying to set a replacement "
2716                     + "startPostponedEnterTransition on " + this);
2717         }
2718         if (mAnimationInfo.mEnterTransitionPostponed) {
2719             mAnimationInfo.mStartEnterTransitionListener = listener;
2720         }
2721         if (listener != null) {
2722             listener.startListening();
2723         }
2724     }
2725 
2726     private AnimationInfo ensureAnimationInfo() {
2727         if (mAnimationInfo == null) {
2728             mAnimationInfo = new AnimationInfo();
2729         }
2730         return mAnimationInfo;
2731     }
2732 
2733     int getNextAnim() {
2734         if (mAnimationInfo == null) {
2735             return 0;
2736         }
2737         return mAnimationInfo.mNextAnim;
2738     }
2739 
2740     void setNextAnim(int animResourceId) {
2741         if (mAnimationInfo == null && animResourceId == 0) {
2742             return; // no change!
2743         }
2744         ensureAnimationInfo().mNextAnim = animResourceId;
2745     }
2746 
2747     int getNextTransition() {
2748         if (mAnimationInfo == null) {
2749             return 0;
2750         }
2751         return mAnimationInfo.mNextTransition;
2752     }
2753 
2754     void setNextTransition(int nextTransition, int nextTransitionStyle) {
2755         if (mAnimationInfo == null && nextTransition == 0 && nextTransitionStyle == 0) {
2756             return; // no change!
2757         }
2758         ensureAnimationInfo();
2759         mAnimationInfo.mNextTransition = nextTransition;
2760         mAnimationInfo.mNextTransitionStyle = nextTransitionStyle;
2761     }
2762 
2763     int getNextTransitionStyle() {
2764         if (mAnimationInfo == null) {
2765             return 0;
2766         }
2767         return mAnimationInfo.mNextTransitionStyle;
2768     }
2769 
2770     SharedElementCallback getEnterTransitionCallback() {
2771         if (mAnimationInfo == null) {
2772             return null;
2773         }
2774         return mAnimationInfo.mEnterTransitionCallback;
2775     }
2776 
2777     SharedElementCallback getExitTransitionCallback() {
2778         if (mAnimationInfo == null) {
2779             return null;
2780         }
2781         return mAnimationInfo.mExitTransitionCallback;
2782     }
2783 
2784     View getAnimatingAway() {
2785         if (mAnimationInfo == null) {
2786             return null;
2787         }
2788         return mAnimationInfo.mAnimatingAway;
2789     }
2790 
2791     void setAnimatingAway(View view) {
2792         ensureAnimationInfo().mAnimatingAway = view;
2793     }
2794 
2795     void setAnimator(Animator animator) {
2796         ensureAnimationInfo().mAnimator = animator;
2797     }
2798 
2799     Animator getAnimator() {
2800         if (mAnimationInfo == null) {
2801             return null;
2802         }
2803         return mAnimationInfo.mAnimator;
2804     }
2805 
2806     int getStateAfterAnimating() {
2807         if (mAnimationInfo == null) {
2808             return 0;
2809         }
2810         return mAnimationInfo.mStateAfterAnimating;
2811     }
2812 
2813     void setStateAfterAnimating(int state) {
2814         ensureAnimationInfo().mStateAfterAnimating = state;
2815     }
2816 
2817     boolean isPostponed() {
2818         if (mAnimationInfo == null) {
2819             return false;
2820         }
2821         return mAnimationInfo.mEnterTransitionPostponed;
2822     }
2823 
2824     boolean isHideReplaced() {
2825         if (mAnimationInfo == null) {
2826             return false;
2827         }
2828         return mAnimationInfo.mIsHideReplaced;
2829     }
2830 
2831     void setHideReplaced(boolean replaced) {
2832         ensureAnimationInfo().mIsHideReplaced = replaced;
2833     }
2834 
2835     /**
2836      * Used internally to be notified when {@link #startPostponedEnterTransition()} has
2837      * been called. This listener will only be called once and then be removed from the
2838      * listeners.
2839      */
2840     interface OnStartEnterTransitionListener {
2841         void onStartEnterTransition();
2842         void startListening();
2843     }
2844 
2845     /**
2846      * Contains all the animation and transition information for a fragment. This will only
2847      * be instantiated for Fragments that have Views.
2848      */
2849     static class AnimationInfo {
2850         // Non-null if the fragment's view hierarchy is currently animating away,
2851         // meaning we need to wait a bit on completely destroying it.  This is the
2852         // view that is animating.
2853         View mAnimatingAway;
2854 
2855         // Non-null if the fragment's view hierarchy is currently animating away with an
2856         // animator instead of an animation.
2857         Animator mAnimator;
2858 
2859         // If mAnimatingAway != null, this is the state we should move to once the
2860         // animation is done.
2861         int mStateAfterAnimating;
2862 
2863         // If app has requested a specific animation, this is the one to use.
2864         int mNextAnim;
2865 
2866         // If app has requested a specific transition, this is the one to use.
2867         int mNextTransition;
2868 
2869         // If app has requested a specific transition style, this is the one to use.
2870         int mNextTransitionStyle;
2871 
2872         private Object mEnterTransition = null;
2873         private Object mReturnTransition = USE_DEFAULT_TRANSITION;
2874         private Object mExitTransition = null;
2875         private Object mReenterTransition = USE_DEFAULT_TRANSITION;
2876         private Object mSharedElementEnterTransition = null;
2877         private Object mSharedElementReturnTransition = USE_DEFAULT_TRANSITION;
2878         private Boolean mAllowReturnTransitionOverlap;
2879         private Boolean mAllowEnterTransitionOverlap;
2880 
2881         SharedElementCallback mEnterTransitionCallback = null;
2882         SharedElementCallback mExitTransitionCallback = null;
2883 
2884         // True when postponeEnterTransition has been called and startPostponeEnterTransition
2885         // hasn't been called yet.
2886         boolean mEnterTransitionPostponed;
2887 
2888         // Listener to wait for startPostponeEnterTransition. After being called, it will
2889         // be set to null
2890         OnStartEnterTransitionListener mStartEnterTransitionListener;
2891 
2892         // True if the View was hidden, but the transition is handling the hide
2893         boolean mIsHideReplaced;
2894     }
2895 }
2896