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