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