Fragment.java revision 291905e34a7f0ae03c68fb2c1b8c34b92d447fbf
1/* 2 * Copyright (C) 2010 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.app; 18 19import android.animation.Animatable; 20import android.content.ComponentCallbacks; 21import android.content.Context; 22import android.content.Intent; 23import android.content.res.Configuration; 24import android.os.Bundle; 25import android.os.Parcel; 26import android.os.Parcelable; 27import android.util.AndroidRuntimeException; 28import android.util.AttributeSet; 29import android.util.Log; 30import android.util.SparseArray; 31import android.view.ContextMenu; 32import android.view.LayoutInflater; 33import android.view.Menu; 34import android.view.MenuInflater; 35import android.view.MenuItem; 36import android.view.View; 37import android.view.ViewGroup; 38import android.view.ContextMenu.ContextMenuInfo; 39import android.view.View.OnCreateContextMenuListener; 40import android.widget.AdapterView; 41 42import java.util.HashMap; 43 44final class FragmentState implements Parcelable { 45 final String mClassName; 46 final int mIndex; 47 final boolean mFromLayout; 48 final int mFragmentId; 49 final int mContainerId; 50 final String mTag; 51 final boolean mRetainInstance; 52 final Bundle mArguments; 53 54 Bundle mSavedFragmentState; 55 56 Fragment mInstance; 57 58 public FragmentState(Fragment frag) { 59 mClassName = frag.getClass().getName(); 60 mIndex = frag.mIndex; 61 mFromLayout = frag.mFromLayout; 62 mFragmentId = frag.mFragmentId; 63 mContainerId = frag.mContainerId; 64 mTag = frag.mTag; 65 mRetainInstance = frag.mRetainInstance; 66 mArguments = frag.mArguments; 67 } 68 69 public FragmentState(Parcel in) { 70 mClassName = in.readString(); 71 mIndex = in.readInt(); 72 mFromLayout = in.readInt() != 0; 73 mFragmentId = in.readInt(); 74 mContainerId = in.readInt(); 75 mTag = in.readString(); 76 mRetainInstance = in.readInt() != 0; 77 mArguments = in.readBundle(); 78 mSavedFragmentState = in.readBundle(); 79 } 80 81 public Fragment instantiate(Activity activity) { 82 if (mInstance != null) { 83 return mInstance; 84 } 85 86 mInstance = Fragment.instantiate(activity, mClassName, mArguments); 87 88 if (mSavedFragmentState != null) { 89 mSavedFragmentState.setClassLoader(activity.getClassLoader()); 90 mInstance.mSavedFragmentState = mSavedFragmentState; 91 } 92 mInstance.setIndex(mIndex); 93 mInstance.mFromLayout = mFromLayout; 94 mInstance.mFragmentId = mFragmentId; 95 mInstance.mContainerId = mContainerId; 96 mInstance.mTag = mTag; 97 mInstance.mRetainInstance = mRetainInstance; 98 99 return mInstance; 100 } 101 102 public int describeContents() { 103 return 0; 104 } 105 106 public void writeToParcel(Parcel dest, int flags) { 107 dest.writeString(mClassName); 108 dest.writeInt(mIndex); 109 dest.writeInt(mFromLayout ? 1 : 0); 110 dest.writeInt(mFragmentId); 111 dest.writeInt(mContainerId); 112 dest.writeString(mTag); 113 dest.writeInt(mRetainInstance ? 1 : 0); 114 dest.writeBundle(mArguments); 115 dest.writeBundle(mSavedFragmentState); 116 } 117 118 public static final Parcelable.Creator<FragmentState> CREATOR 119 = new Parcelable.Creator<FragmentState>() { 120 public FragmentState createFromParcel(Parcel in) { 121 return new FragmentState(in); 122 } 123 124 public FragmentState[] newArray(int size) { 125 return new FragmentState[size]; 126 } 127 }; 128} 129 130/** 131 * A Fragment is a piece of an application's user interface or behavior 132 * that can be placed in an {@link Activity}. Interaction with fragments 133 * is done through {@link FragmentManager}, which can be obtained via 134 * {@link Activity#getFragmentManager() Activity.getFragmentManager()} and 135 * {@link Fragment#getFragmentManager() Fragment.getFragmentManager()}. 136 * 137 * <p>The Fragment class can be used many ways to achieve a wide variety of 138 * results. It is core, it represents a particular operation or interface 139 * that is running within a larger {@link Activity}. A Fragment is closely 140 * tied to the Activity it is in, and can not be used apart from one. Though 141 * Fragment defines its own lifecycle, that lifecycle is dependent on its 142 * activity: if the activity is stopped, no fragments inside of it can be 143 * started; when the activity is destroyed, all fragments will be destroyed. 144 * 145 * <p>All subclasses of Fragment must include a public empty constructor. 146 * The framework will often re-instantiate a fragment class when needed, 147 * in particular during state restore, and needs to be able to find this 148 * constructor to instantiate it. If the empty constructor is not available, 149 * a runtime exception will occur in some cases during state restore. 150 * 151 * <p>Topics covered here: 152 * <ol> 153 * <li><a href="#Lifecycle">Lifecycle</a> 154 * <li><a href="#Layout">Layout</a> 155 * <li><a href="#BackStack">Back Stack</a> 156 * </ol> 157 * 158 * <a name="Lifecycle"></a> 159 * <h3>Lifecycle</h3> 160 * 161 * <p>Though a Fragment's lifecycle is tied to its owning activity, it has 162 * its own wrinkle on the standard activity lifecycle. It includes basic 163 * activity lifecycle methods such as {@link #onResume}, but also important 164 * are methods related to interactions with the activity and UI generation. 165 * 166 * <p>The core series of lifecycle methods that are called to bring a fragment 167 * up to resumed state (interacting with the user) are: 168 * 169 * <ol> 170 * <li> {@link #onAttach} called once the fragment is associated with its activity. 171 * <li> {@link #onCreate} called to do initial creation of the fragment. 172 * <li> {@link #onCreateView} creates and returns the view hierarchy associated 173 * with the fragment. 174 * <li> {@link #onActivityCreated} tells the fragment that its activity has 175 * completed its own {@link Activity#onCreate Activity.onCreaate}. 176 * <li> {@link #onStart} makes the fragment visible to the user (based on its 177 * containing activity being started). 178 * <li> {@link #onResume} makes the fragment interacting with the user (based on its 179 * containing activity being resumed). 180 * </ol> 181 * 182 * <p>As a fragment is no longer being used, it goes through a reverse 183 * series of callbacks: 184 * 185 * <ol> 186 * <li> {@link #onPause} fragment is no longer interacting with the user either 187 * because its activity is being paused or a fragment operation is modifying it 188 * in the activity. 189 * <li> {@link #onStop} fragment is no longer visible to the user either 190 * because its activity is being stopped or a fragment operation is modifying it 191 * in the activity. 192 * <li> {@link #onDestroyView} allows the fragment to clean up resources 193 * associated with its View. 194 * <li> {@link #onDestroy} called to do final cleanup of the fragment's state. 195 * <li> {@link #onDetach} called immediately prior to the fragment no longer 196 * being associated with its activity. 197 * </ol> 198 * 199 * <a name="Layout"></a> 200 * <h3>Layout</h3> 201 * 202 * <p>Fragments can be used as part of your application's layout, allowing 203 * you to better modularize your code and more easily adjust your user 204 * interface to the screen it is running on. As an example, we can look 205 * at a simple program consisting of a list of items, and display of the 206 * details of each item.</p> 207 * 208 * <p>An activity's layout XML can include <code><fragment></code> tags 209 * to embed fragment instances inside of the layout. For example, here is 210 * a simply layout that embeds one fragment:</p> 211 * 212 * {@sample development/samples/ApiDemos/res/layout/fragment_layout.xml layout} 213 * 214 * <p>The layout is installed in the activity in the normal way:</p> 215 * 216 * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java 217 * main} 218 * 219 * <p>The titles fragment, showing a list of titles, is very simple, relying 220 * on {@link ListFragment} for most of its work. Note the implementation of 221 * clicking an item, which can either update 222 * the content of the details fragment or start a new activity show the 223 * details depending on whether the current activity's layout can show the 224 * details.</p> 225 * 226 * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java 227 * titles} 228 * 229 * <p>The details fragment showing the contents of selected item here just 230 * displays a string of text based on an index of a string array built in to 231 * the app:</p> 232 * 233 * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java 234 * details} 235 * 236 * <p>In this case when the user clicks on a title, there is no details 237 * fragment in the current activity, so the title title fragment's click code will 238 * launch a new activity to display the details fragment:</p> 239 * 240 * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java 241 * details_activity} 242 * 243 * <p>However the screen may be large enough to show both the list of titles 244 * and details about the currently selected title. To use such a layout on 245 * a landscape screen, this alternative layout can be placed under layout-land:</p> 246 * 247 * {@sample development/samples/ApiDemos/res/layout-land/fragment_layout.xml layout} 248 * 249 * <p>Note how the prior code will adjust to this alternative UI flow: the 250 * titles fragment will now show its text inside of its activity, and the 251 * details activity will finish of it finds itself running in a configuration 252 * where the details can be shown inline. 253 * 254 * <a name="BackStack"></a> 255 * <h3>Back Stack</h3> 256 * 257 * <p>The transaction in which fragments are modified can be placed on an 258 * internal back-stack of the owning activity. When the user presses back 259 * in the activity, any transactions on the back stack are popped off before 260 * the activity itself is finished. 261 * 262 * <p>For example, consider this simple fragment that is instantiated with 263 * an integer argument and displays that in a TextView in its UI:</p> 264 * 265 * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentStack.java 266 * fragment} 267 * 268 * <p>A function that creates a new instance of the fragment, replacing 269 * whatever current fragment instance is being shown and pushing that change 270 * on to the back stack could be written as: 271 * 272 * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentStack.java 273 * add_stack} 274 * 275 * <p>After each call to this function, a new entry is on the stack, and 276 * pressing back will pop it to return the user to whatever previous state 277 * the activity UI was in. 278 */ 279public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener { 280 private static final HashMap<String, Class<?>> sClassMap = 281 new HashMap<String, Class<?>>(); 282 283 static final int INITIALIZING = 0; // Not yet created. 284 static final int CREATED = 1; // Created. 285 static final int ACTIVITY_CREATED = 2; // The activity has finished its creation. 286 static final int STARTED = 3; // Created and started, not resumed. 287 static final int RESUMED = 4; // Created started and resumed. 288 289 int mState = INITIALIZING; 290 291 // When instantiated from saved state, this is the saved state. 292 Bundle mSavedFragmentState; 293 SparseArray<Parcelable> mSavedViewState; 294 295 // Index into active fragment array. 296 int mIndex = -1; 297 298 // Internal unique name for this fragment; 299 String mWho; 300 301 // Construction arguments; 302 Bundle mArguments; 303 304 // Target fragment. 305 Fragment mTarget; 306 307 // Target request code. 308 int mTargetRequestCode; 309 310 // True if the fragment is in the list of added fragments. 311 boolean mAdded; 312 313 // True if the fragment is in the resumed state. 314 boolean mResumed; 315 316 // Set to true if this fragment was instantiated from a layout file. 317 boolean mFromLayout; 318 319 // Number of active back stack entries this fragment is in. 320 int mBackStackNesting; 321 322 // Set as soon as a fragment is added to a transaction (or removed), 323 // to be able to do validation. 324 Activity mImmediateActivity; 325 326 // Activity this fragment is attached to. 327 Activity mActivity; 328 329 // The optional identifier for this fragment -- either the container ID if it 330 // was dynamically added to the view hierarchy, or the ID supplied in 331 // layout. 332 int mFragmentId; 333 334 // When a fragment is being dynamically added to the view hierarchy, this 335 // is the identifier of the parent container it is being added to. 336 int mContainerId; 337 338 // The optional named tag for this fragment -- usually used to find 339 // fragments that are not part of the layout. 340 String mTag; 341 342 // Set to true when the app has requested that this fragment be hidden 343 // from the user. 344 boolean mHidden; 345 346 // If set this fragment would like its instance retained across 347 // configuration changes. 348 boolean mRetainInstance; 349 350 // If set this fragment is being retained across the current config change. 351 boolean mRetaining; 352 353 // If set this fragment has menu items to contribute. 354 boolean mHasMenu; 355 356 // Used to verify that subclasses call through to super class. 357 boolean mCalled; 358 359 // If app has requested a specific animation, this is the one to use. 360 int mNextAnim; 361 362 // The parent container of the fragment after dynamically added to UI. 363 ViewGroup mContainer; 364 365 // The View generated for this fragment. 366 View mView; 367 368 LoaderManagerImpl mLoaderManager; 369 boolean mStarted; 370 boolean mCheckedForLoaderManager; 371 372 /** 373 * Thrown by {@link Fragment#instantiate(Context, String, Bundle)} when 374 * there is an instantiation failure. 375 */ 376 static public class InstantiationException extends AndroidRuntimeException { 377 public InstantiationException(String msg, Exception cause) { 378 super(msg, cause); 379 } 380 } 381 382 /** 383 * Default constructor. <strong>Every</strong> fragment must have an 384 * empty constructor, so it can be instantiated when restoring its 385 * activity's state. It is strongly recommended that subclasses do not 386 * have other constructors with parameters, since these constructors 387 * will not be called when the fragment is re-instantiated; instead, 388 * arguments can be supplied by the caller with {@link #setArguments} 389 * and later retrieved by the Fragment with {@link #getArguments}. 390 * 391 * <p>Applications should generally not implement a constructor. The 392 * first place application code an run where the fragment is ready to 393 * be used is in {@link #onAttach(Activity)}, the point where the fragment 394 * is actually associated with its activity. Some applications may also 395 * want to implement {@link #onInflate} to retrieve attributes from a 396 * layout resource, though should take care here because this happens for 397 * the fragment is attached to its activity. 398 */ 399 public Fragment() { 400 } 401 402 /** 403 * Like {@link #instantiate(Context, String, Bundle)} but with a null 404 * argument Bundle. 405 */ 406 public static Fragment instantiate(Context context, String fname) { 407 return instantiate(context, fname, null); 408 } 409 410 /** 411 * Create a new instance of a Fragment with the given class name. This is 412 * the same as calling its empty constructor. 413 * 414 * @param context The calling context being used to instantiate the fragment. 415 * This is currently just used to get its ClassLoader. 416 * @param fname The class name of the fragment to instantiate. 417 * @param args Bundle of arguments to supply to the fragment, which it 418 * can retrieve with {@link #getArguments()}. May be null. 419 * @return Returns a new fragment instance. 420 * @throws InstantiationException If there is a failure in instantiating 421 * the given fragment class. This is a runtime exception; it is not 422 * normally expected to happen. 423 */ 424 public static Fragment instantiate(Context context, String fname, Bundle args) { 425 try { 426 Class<?> clazz = sClassMap.get(fname); 427 if (clazz == null) { 428 // Class not found in the cache, see if it's real, and try to add it 429 clazz = context.getClassLoader().loadClass(fname); 430 sClassMap.put(fname, clazz); 431 } 432 Fragment f = (Fragment)clazz.newInstance(); 433 if (args != null) { 434 args.setClassLoader(f.getClass().getClassLoader()); 435 f.mArguments = args; 436 } 437 return f; 438 } catch (ClassNotFoundException e) { 439 throw new InstantiationException("Unable to instantiate fragment " + fname 440 + ": make sure class name exists, is public, and has an" 441 + " empty constructor that is public", e); 442 } catch (java.lang.InstantiationException e) { 443 throw new InstantiationException("Unable to instantiate fragment " + fname 444 + ": make sure class name exists, is public, and has an" 445 + " empty constructor that is public", e); 446 } catch (IllegalAccessException e) { 447 throw new InstantiationException("Unable to instantiate fragment " + fname 448 + ": make sure class name exists, is public, and has an" 449 + " empty constructor that is public", e); 450 } 451 } 452 453 void restoreViewState() { 454 if (mSavedViewState != null) { 455 mView.restoreHierarchyState(mSavedViewState); 456 mSavedViewState = null; 457 } 458 } 459 460 void setIndex(int index) { 461 mIndex = index; 462 mWho = "android:fragment:" + mIndex; 463 } 464 465 void clearIndex() { 466 mIndex = -1; 467 mWho = null; 468 } 469 470 /** 471 * Subclasses can not override equals(). 472 */ 473 @Override final public boolean equals(Object o) { 474 return super.equals(o); 475 } 476 477 /** 478 * Subclasses can not override hashCode(). 479 */ 480 @Override final public int hashCode() { 481 return super.hashCode(); 482 } 483 484 @Override 485 public String toString() { 486 StringBuilder sb = new StringBuilder(128); 487 sb.append("Fragment{"); 488 sb.append(Integer.toHexString(System.identityHashCode(this))); 489 if (mIndex >= 0) { 490 sb.append(" #"); 491 sb.append(mIndex); 492 } 493 if (mFragmentId != 0) { 494 sb.append(" id=0x"); 495 sb.append(Integer.toHexString(mFragmentId)); 496 } 497 if (mTag != null) { 498 sb.append(" "); 499 sb.append(mTag); 500 } 501 sb.append('}'); 502 return sb.toString(); 503 } 504 505 /** 506 * Return the identifier this fragment is known by. This is either 507 * the android:id value supplied in a layout or the container view ID 508 * supplied when adding the fragment. 509 */ 510 final public int getId() { 511 return mFragmentId; 512 } 513 514 /** 515 * Get the tag name of the fragment, if specified. 516 */ 517 final public String getTag() { 518 return mTag; 519 } 520 521 /** 522 * Supply the construction arguments for this fragment. This can only 523 * be called before the fragment has been attached to its activity; that 524 * is, you should call it immediately after constructing the fragment. The 525 * arguments supplied here will be retained across fragment destroy and 526 * creation. 527 */ 528 public void setArguments(Bundle args) { 529 if (mIndex >= 0) { 530 throw new IllegalStateException("Fragment already active"); 531 } 532 mArguments = args; 533 } 534 535 /** 536 * Return the arguments supplied when the fragment was instantiated, 537 * if any. 538 */ 539 final public Bundle getArguments() { 540 return mArguments; 541 } 542 543 /** 544 * Optional target for this fragment. This may be used, for example, 545 * if this fragment is being started by another, and when done wants to 546 * give a result back to the first. The target set here is retained 547 * across instances via {@link FragmentManager#putFragment 548 * FragmentManager.putFragment()}. 549 * 550 * @param fragment The fragment that is the target of this one. 551 * @param requestCode Optional request code, for convenience if you 552 * are going to call back with {@link #onActivityResult(int, int, Intent)}. 553 */ 554 public void setTargetFragment(Fragment fragment, int requestCode) { 555 mTarget = fragment; 556 mTargetRequestCode = requestCode; 557 } 558 559 /** 560 * Return the target fragment set by {@link #setTargetFragment}. 561 */ 562 final public Fragment getTargetFragment() { 563 return mTarget; 564 } 565 566 /** 567 * Return the target request code set by {@link #setTargetFragment}. 568 */ 569 final public int getTargetRequestCode() { 570 return mTargetRequestCode; 571 } 572 573 /** 574 * Return the Activity this fragment is currently associated with. 575 */ 576 final public Activity getActivity() { 577 return mActivity; 578 } 579 580 /** 581 * Return the FragmentManager for interacting with fragments associated 582 * with this fragment's activity. 583 */ 584 final public FragmentManager getFragmentManager() { 585 return mActivity.mFragments; 586 } 587 588 /** 589 * Return true if the fragment is currently added to its activity. 590 */ 591 final public boolean isAdded() { 592 return mActivity != null && mActivity.mFragments.mAdded.contains(this); 593 } 594 595 /** 596 * Return true if the fragment is in the resumed state. This is true 597 * for the duration of {@link #onResume()} and {@link #onPause()} as well. 598 */ 599 final public boolean isResumed() { 600 return mResumed; 601 } 602 603 /** 604 * Return true if the fragment is currently visible to the user. This means 605 * it: (1) has been added, (2) has its view attached to the window, and 606 * (3) is not hidden. 607 */ 608 final public boolean isVisible() { 609 return isAdded() && !isHidden() && mView != null 610 && mView.getWindowToken() != null && mView.getVisibility() == View.VISIBLE; 611 } 612 613 /** 614 * Return true if the fragment has been hidden. By default fragments 615 * are shown. You can find out about changes to this state with 616 * {@link #onHiddenChanged}. Note that the hidden state is orthogonal 617 * to other states -- that is, to be visible to the user, a fragment 618 * must be both started and not hidden. 619 */ 620 final public boolean isHidden() { 621 return mHidden; 622 } 623 624 /** 625 * Called when the hidden state (as returned by {@link #isHidden()} of 626 * the fragment has changed. Fragments start out not hidden; this will 627 * be called whenever the fragment changes state from that. 628 * @param hidden True if the fragment is now hidden, false if it is not 629 * visible. 630 */ 631 public void onHiddenChanged(boolean hidden) { 632 } 633 634 /** 635 * Control whether a fragment instance is retained across Activity 636 * re-creation (such as from a configuration change). This can only 637 * be used with fragments not in the back stack. If set, the fragment 638 * lifecycle will be slightly different when an activity is recreated: 639 * <ul> 640 * <li> {@link #onDestroy()} will not be called (but {@link #onDetach()} still 641 * will be, because the fragment is being detached from its current activity). 642 * <li> {@link #onCreate(Bundle)} will not be called since the fragment 643 * is not being re-created. 644 * <li> {@link #onAttach(Activity)} and {@link #onActivityCreated(Bundle)} <b>will</b> 645 * still be called. 646 * </ul> 647 */ 648 public void setRetainInstance(boolean retain) { 649 mRetainInstance = retain; 650 } 651 652 final public boolean getRetainInstance() { 653 return mRetainInstance; 654 } 655 656 /** 657 * Report that this fragment would like to participate in populating 658 * the options menu by receiving a call to {@link #onCreateOptionsMenu} 659 * and related methods. 660 * 661 * @param hasMenu If true, the fragment has menu items to contribute. 662 */ 663 public void setHasOptionsMenu(boolean hasMenu) { 664 if (mHasMenu != hasMenu) { 665 mHasMenu = hasMenu; 666 if (isAdded() && !isHidden()) { 667 mActivity.invalidateOptionsMenu(); 668 } 669 } 670 } 671 672 /** 673 * Return the LoaderManager for this fragment, creating it if needed. 674 */ 675 public LoaderManager getLoaderManager() { 676 if (mLoaderManager != null) { 677 return mLoaderManager; 678 } 679 mCheckedForLoaderManager = true; 680 mLoaderManager = mActivity.getLoaderManager(mIndex, mStarted, true); 681 return mLoaderManager; 682 } 683 684 /** 685 * Call {@link Activity#startActivity(Intent)} on the fragment's 686 * containing Activity. 687 */ 688 public void startActivity(Intent intent) { 689 mActivity.startActivityFromFragment(this, intent, -1); 690 } 691 692 /** 693 * Call {@link Activity#startActivityForResult(Intent, int)} on the fragment's 694 * containing Activity. 695 */ 696 public void startActivityForResult(Intent intent, int requestCode) { 697 mActivity.startActivityFromFragment(this, intent, requestCode); 698 } 699 700 /** 701 * Receive the result from a previous call to 702 * {@link #startActivityForResult(Intent, int)}. This follows the 703 * related Activity API as described there in 704 * {@link Activity#onActivityResult(int, int, Intent)}. 705 * 706 * @param requestCode The integer request code originally supplied to 707 * startActivityForResult(), allowing you to identify who this 708 * result came from. 709 * @param resultCode The integer result code returned by the child activity 710 * through its setResult(). 711 * @param data An Intent, which can return result data to the caller 712 * (various data can be attached to Intent "extras"). 713 */ 714 public void onActivityResult(int requestCode, int resultCode, Intent data) { 715 } 716 717 /** 718 * Called when a fragment is being created as part of a view layout 719 * inflation, typically from setting the content view of an activity. This 720 * will be called immediately after the fragment is created from a <fragment> 721 * tag in a layout file. Note this is <em>before</em> the fragment's 722 * {@link #onAttach(Activity)} has been called; all you should do here is 723 * parse the attributes and save them away. A convenient thing to do is 724 * simply copy them into a Bundle that is given to {@link #setArguments(Bundle)}. 725 * 726 * <p>This is called every time the fragment is inflated, even if it is 727 * being inflated into a new instance with saved state. Because a fragment's 728 * arguments are retained across instances, it may make no sense to re-parse 729 * the attributes into new arguments. You may want to first check 730 * {@link #getArguments()} and only parse the attributes if it returns null, 731 * the assumption being that if it is non-null those are the same arguments 732 * from the first time the fragment was inflated. (That said, you may want 733 * to have layouts change for different configurations such as landscape 734 * and portrait, which can have different attributes. If so, you will need 735 * to re-parse the attributes each time this is called to generate new 736 * arguments.)</p> 737 * 738 * @param attrs The attributes at the tag where the fragment is 739 * being created. 740 * @param savedInstanceState If the fragment is being re-created from 741 * a previous saved state, this is the state. 742 */ 743 public void onInflate(AttributeSet attrs, Bundle savedInstanceState) { 744 mCalled = true; 745 } 746 747 /** 748 * Called when a fragment is first attached to its activity. 749 * {@link #onCreate(Bundle)} will be called after this. 750 */ 751 public void onAttach(Activity activity) { 752 mCalled = true; 753 } 754 755 /** 756 * Called when a fragment loads an animation. 757 */ 758 public Animatable onCreateAnimatable(int transit, boolean enter, int nextAnim) { 759 return null; 760 } 761 762 /** 763 * Called to do initial creation of a fragment. This is called after 764 * {@link #onAttach(Activity)} and before 765 * {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}. 766 * 767 * <p>Note that this can be called while the fragment's activity is 768 * still in the process of being created. As such, you can not rely 769 * on things like the activity's content view hierarchy being initialized 770 * at this point. If you want to do work once the activity itself is 771 * created, see {@link #onActivityCreated(Bundle)}. 772 * 773 * @param savedInstanceState If the fragment is being re-created from 774 * a previous saved state, this is the state. 775 */ 776 public void onCreate(Bundle savedInstanceState) { 777 mCalled = true; 778 } 779 780 /** 781 * Called to have the fragment instantiate its user interface view. 782 * This is optional, and non-graphical fragments can return null (which 783 * is the default implementation). This will be called between 784 * {@link #onCreate(Bundle)} and {@link #onActivityCreated(Bundle)}. 785 * 786 * <p>If you return a View from here, you will later be called in 787 * {@link #onDestroyView} when the view is being released. 788 * 789 * @param inflater The LayoutInflater object that can be used to inflate 790 * any views in the fragment, 791 * @param container If non-null, this is the parent view that the fragment's 792 * UI should be attached to. The fragment should not add the view itself, 793 * but this can be used to generate the LayoutParams of the view. 794 * @param savedInstanceState If non-null, this fragment is being re-constructed 795 * from a previous saved state as given here. 796 * 797 * @return Return the View for the fragment's UI, or null. 798 */ 799 public View onCreateView(LayoutInflater inflater, ViewGroup container, 800 Bundle savedInstanceState) { 801 return null; 802 } 803 804 public View getView() { 805 return mView; 806 } 807 808 /** 809 * Called when the fragment's activity has been created and this 810 * fragment's view hierarchy instantiated. It can be used to do final 811 * initialization once these pieces are in place, such as retrieving 812 * views or restoring state. It is also useful for fragments that use 813 * {@link #setRetainInstance(boolean)} to retain their instance, 814 * as this callback tells the fragment when it is fully associated with 815 * the new activity instance. This is called after {@link #onCreateView} 816 * and before {@link #onStart()}. 817 * 818 * @param savedInstanceState If the fragment is being re-created from 819 * a previous saved state, this is the state. 820 */ 821 public void onActivityCreated(Bundle savedInstanceState) { 822 mCalled = true; 823 } 824 825 /** 826 * Called when the Fragment is visible to the user. This is generally 827 * tied to {@link Activity#onStart() Activity.onStart} of the containing 828 * Activity's lifecycle. 829 */ 830 public void onStart() { 831 mCalled = true; 832 mStarted = true; 833 if (!mCheckedForLoaderManager) { 834 mCheckedForLoaderManager = true; 835 mLoaderManager = mActivity.getLoaderManager(mIndex, mStarted, false); 836 } 837 if (mLoaderManager != null) { 838 mLoaderManager.doStart(); 839 } 840 } 841 842 /** 843 * Called when the fragment is visible to the user and actively running. 844 * This is generally 845 * tied to {@link Activity#onResume() Activity.onResume} of the containing 846 * Activity's lifecycle. 847 */ 848 public void onResume() { 849 mCalled = true; 850 } 851 852 public void onSaveInstanceState(Bundle outState) { 853 } 854 855 public void onConfigurationChanged(Configuration newConfig) { 856 mCalled = true; 857 } 858 859 /** 860 * Called when the Fragment is no longer resumed. This is generally 861 * tied to {@link Activity#onPause() Activity.onPause} of the containing 862 * Activity's lifecycle. 863 */ 864 public void onPause() { 865 mCalled = true; 866 } 867 868 /** 869 * Called when the Fragment is no longer started. This is generally 870 * tied to {@link Activity#onStop() Activity.onStop} of the containing 871 * Activity's lifecycle. 872 */ 873 public void onStop() { 874 mCalled = true; 875 } 876 877 public void onLowMemory() { 878 mCalled = true; 879 } 880 881 /** 882 * Called when the view previously created by {@link #onCreateView} has 883 * been detached from the fragment. The next time the fragment needs 884 * to be displayed, a new view will be created. This is called 885 * after {@link #onStop()} and before {@link #onDestroy()}. It is called 886 * <em>regardless</em> of whether {@link #onCreateView} returned a 887 * non-null view. Internally it is called after the view's state has 888 * been saved but before it has been removed from its parent. 889 */ 890 public void onDestroyView() { 891 mCalled = true; 892 } 893 894 /** 895 * Called when the fragment is no longer in use. This is called 896 * after {@link #onStop()} and before {@link #onDetach()}. 897 */ 898 public void onDestroy() { 899 mCalled = true; 900 //Log.v("foo", "onDestroy: mCheckedForLoaderManager=" + mCheckedForLoaderManager 901 // + " mLoaderManager=" + mLoaderManager); 902 if (!mCheckedForLoaderManager) { 903 mCheckedForLoaderManager = true; 904 mLoaderManager = mActivity.getLoaderManager(mIndex, mStarted, false); 905 } 906 if (mLoaderManager != null) { 907 mLoaderManager.doDestroy(); 908 } 909 } 910 911 /** 912 * Called when the fragment is no longer attached to its activity. This 913 * is called after {@link #onDestroy()}. 914 */ 915 public void onDetach() { 916 mCalled = true; 917 } 918 919 /** 920 * Initialize the contents of the Activity's standard options menu. You 921 * should place your menu items in to <var>menu</var>. For this method 922 * to be called, you must have first called {@link #setHasOptionsMenu}. See 923 * {@link Activity#onCreateOptionsMenu(Menu) Activity.onCreateOptionsMenu} 924 * for more information. 925 * 926 * @param menu The options menu in which you place your items. 927 * 928 * @see #setHasOptionsMenu 929 * @see #onPrepareOptionsMenu 930 * @see #onOptionsItemSelected 931 */ 932 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 933 } 934 935 /** 936 * Prepare the Screen's standard options menu to be displayed. This is 937 * called right before the menu is shown, every time it is shown. You can 938 * use this method to efficiently enable/disable items or otherwise 939 * dynamically modify the contents. See 940 * {@link Activity#onPrepareOptionsMenu(Menu) Activity.onPrepareOptionsMenu} 941 * for more information. 942 * 943 * @param menu The options menu as last shown or first initialized by 944 * onCreateOptionsMenu(). 945 * 946 * @see #setHasOptionsMenu 947 * @see #onCreateOptionsMenu 948 */ 949 public void onPrepareOptionsMenu(Menu menu) { 950 } 951 952 /** 953 * This hook is called whenever an item in your options menu is selected. 954 * The default implementation simply returns false to have the normal 955 * processing happen (calling the item's Runnable or sending a message to 956 * its Handler as appropriate). You can use this method for any items 957 * for which you would like to do processing without those other 958 * facilities. 959 * 960 * <p>Derived classes should call through to the base class for it to 961 * perform the default menu handling. 962 * 963 * @param item The menu item that was selected. 964 * 965 * @return boolean Return false to allow normal menu processing to 966 * proceed, true to consume it here. 967 * 968 * @see #onCreateOptionsMenu 969 */ 970 public boolean onOptionsItemSelected(MenuItem item) { 971 return false; 972 } 973 974 /** 975 * This hook is called whenever the options menu is being closed (either by the user canceling 976 * the menu with the back/menu button, or when an item is selected). 977 * 978 * @param menu The options menu as last shown or first initialized by 979 * onCreateOptionsMenu(). 980 */ 981 public void onOptionsMenuClosed(Menu menu) { 982 } 983 984 /** 985 * Called when a context menu for the {@code view} is about to be shown. 986 * Unlike {@link #onCreateOptionsMenu}, this will be called every 987 * time the context menu is about to be shown and should be populated for 988 * the view (or item inside the view for {@link AdapterView} subclasses, 989 * this can be found in the {@code menuInfo})). 990 * <p> 991 * Use {@link #onContextItemSelected(android.view.MenuItem)} to know when an 992 * item has been selected. 993 * <p> 994 * The default implementation calls up to 995 * {@link Activity#onCreateContextMenu Activity.onCreateContextMenu}, though 996 * you can not call this implementation if you don't want that behavior. 997 * <p> 998 * It is not safe to hold onto the context menu after this method returns. 999 * {@inheritDoc} 1000 */ 1001 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { 1002 getActivity().onCreateContextMenu(menu, v, menuInfo); 1003 } 1004 1005 /** 1006 * Registers a context menu to be shown for the given view (multiple views 1007 * can show the context menu). This method will set the 1008 * {@link OnCreateContextMenuListener} on the view to this fragment, so 1009 * {@link #onCreateContextMenu(ContextMenu, View, ContextMenuInfo)} will be 1010 * called when it is time to show the context menu. 1011 * 1012 * @see #unregisterForContextMenu(View) 1013 * @param view The view that should show a context menu. 1014 */ 1015 public void registerForContextMenu(View view) { 1016 view.setOnCreateContextMenuListener(this); 1017 } 1018 1019 /** 1020 * Prevents a context menu to be shown for the given view. This method will 1021 * remove the {@link OnCreateContextMenuListener} on the view. 1022 * 1023 * @see #registerForContextMenu(View) 1024 * @param view The view that should stop showing a context menu. 1025 */ 1026 public void unregisterForContextMenu(View view) { 1027 view.setOnCreateContextMenuListener(null); 1028 } 1029 1030 /** 1031 * This hook is called whenever an item in a context menu is selected. The 1032 * default implementation simply returns false to have the normal processing 1033 * happen (calling the item's Runnable or sending a message to its Handler 1034 * as appropriate). You can use this method for any items for which you 1035 * would like to do processing without those other facilities. 1036 * <p> 1037 * Use {@link MenuItem#getMenuInfo()} to get extra information set by the 1038 * View that added this menu item. 1039 * <p> 1040 * Derived classes should call through to the base class for it to perform 1041 * the default menu handling. 1042 * 1043 * @param item The context menu item that was selected. 1044 * @return boolean Return false to allow normal context menu processing to 1045 * proceed, true to consume it here. 1046 */ 1047 public boolean onContextItemSelected(MenuItem item) { 1048 return false; 1049 } 1050 1051 void performStop() { 1052 onStop(); 1053 if (mStarted) { 1054 mStarted = false; 1055 if (!mCheckedForLoaderManager) { 1056 mCheckedForLoaderManager = true; 1057 mLoaderManager = mActivity.getLoaderManager(mIndex, mStarted, false); 1058 } 1059 if (mLoaderManager != null) { 1060 if (mActivity == null || !mActivity.mChangingConfigurations) { 1061 mLoaderManager.doStop(); 1062 } else { 1063 mLoaderManager.doRetain(); 1064 } 1065 } 1066 } 1067 } 1068} 1069