Fragment.java revision 17d9d287fd6d180c6c48d62305ae4d7265056410
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
17package androidx.fragment.app;
18
19import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
20
21import android.animation.Animator;
22import android.app.Activity;
23import android.content.ComponentCallbacks;
24import android.content.Context;
25import android.content.Intent;
26import android.content.IntentSender;
27import android.content.res.Configuration;
28import android.content.res.Resources;
29import android.os.Bundle;
30import android.os.Looper;
31import android.os.Parcel;
32import android.os.Parcelable;
33import android.util.AttributeSet;
34import android.util.SparseArray;
35import android.view.ContextMenu;
36import android.view.ContextMenu.ContextMenuInfo;
37import android.view.LayoutInflater;
38import android.view.Menu;
39import android.view.MenuInflater;
40import android.view.MenuItem;
41import android.view.View;
42import android.view.View.OnCreateContextMenuListener;
43import android.view.ViewGroup;
44import android.view.animation.Animation;
45import android.widget.AdapterView;
46
47import androidx.annotation.CallSuper;
48import androidx.annotation.MainThread;
49import androidx.annotation.NonNull;
50import androidx.annotation.Nullable;
51import androidx.annotation.RestrictTo;
52import androidx.annotation.StringRes;
53import androidx.collection.SimpleArrayMap;
54import androidx.core.app.SharedElementCallback;
55import androidx.core.util.DebugUtils;
56import androidx.core.view.LayoutInflaterCompat;
57import androidx.lifecycle.Lifecycle;
58import androidx.lifecycle.LifecycleOwner;
59import androidx.lifecycle.LifecycleRegistry;
60import androidx.lifecycle.LiveData;
61import androidx.lifecycle.MutableLiveData;
62import androidx.lifecycle.ViewModelStore;
63import androidx.lifecycle.ViewModelStoreOwner;
64import androidx.loader.app.LoaderManager;
65
66import java.io.FileDescriptor;
67import java.io.PrintWriter;
68import 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 */
85public 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
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
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
312    public LiveData<LifecycleOwner> getViewLifecycleOwnerLiveData() {
313        return mViewLifecycleOwnerLiveData;
314    }
315
316    @NonNull
317    @Override
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
336        SavedState(Bundle state) {
337            mState = state;
338        }
339
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
348        public int describeContents() {
349            return 0;
350        }
351
352        @Override
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 {
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     */
397    public Fragment() {
398    }
399
400    /**
401     * Like {@link #instantiate(Context, String, Bundle)} but with a null
402     * argument Bundle.
403     */
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     */
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     */
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
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
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
501    final boolean isInBackStack() {
502        return mBackStackNesting > 0;
503    }
504
505    /**
506     * Subclasses can not override equals().
507     */
508    @Override final public boolean equals(Object o) {
509        return super.equals(o);
510    }
511
512    /**
513     * Subclasses can not override hashCode().
514     */
515    @Override final public int hashCode() {
516        return super.hashCode();
517    }
518
519    @Override
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     */
544    final public int getId() {
545        return mFragmentId;
546    }
547
548    /**
549     * Get the tag name of the fragment, if specified.
550     */
551    @Nullable
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     */
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
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     */
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     */
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")
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
649    final public Fragment getTargetFragment() {
650        return mTarget;
651    }
652
653    /**
654     * Return the target request code set by {@link #setTargetFragment}.
655     */
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
857    final public Fragment getParentFragment() {
858        return mParentFragment;
859    }
860
861    /**
862     * Return true if the fragment is currently added to its activity.
863     */
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     */
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     */
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     */
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     */
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     */
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     */
922    final public boolean isHidden() {
923        return mHidden;
924    }
925
926    /** @hide */
927    @RestrictTo(LIBRARY_GROUP)
928    final public boolean hasOptionsMenu() {
929        return mHasMenu;
930    }
931
932    /** @hide */
933    @RestrictTo(LIBRARY_GROUP)
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     */
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     */
961    public void setRetainInstance(boolean retain) {
962        mRetainInstance = retain;
963    }
964
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     */
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     */
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     */
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