Fragment.java revision 727782053ced0cac5beadc2c7ee9382d0f1ba1f5
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 /** 853 * Called to ask the fragment to save its current dynamic state, so it 854 * can later be reconstructed in a new instance of its process is 855 * restarted. If a new instance of the fragment later needs to be 856 * created, the data you place in the Bundle here will be available 857 * in the Bundle given to {@link #onCreate(Bundle)}, 858 * {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}, and 859 * {@link #onActivityCreated(Bundle)}. 860 * 861 * <p>This corresponds to {@link Activity#onSaveInstanceState(Bundle) 862 * Activity.onnSaveInstanceState(Bundle)} and most of the discussion there 863 * applies here as well. Note however: <em>this method may be called 864 * at any time before {@link #onDestroy()}</em>. There are many situations 865 * where a fragment may be mostly torn down (such as when placed on the 866 * back stack with no UI showing), but its state will not be saved until 867 * its owning activity actually needs to save its state. 868 * 869 * @param outState Bundle in which to place your saved state. 870 */ 871 public void onSaveInstanceState(Bundle outState) { 872 } 873 874 public void onConfigurationChanged(Configuration newConfig) { 875 mCalled = true; 876 } 877 878 /** 879 * Called when the Fragment is no longer resumed. This is generally 880 * tied to {@link Activity#onPause() Activity.onPause} of the containing 881 * Activity's lifecycle. 882 */ 883 public void onPause() { 884 mCalled = true; 885 } 886 887 /** 888 * Called when the Fragment is no longer started. This is generally 889 * tied to {@link Activity#onStop() Activity.onStop} of the containing 890 * Activity's lifecycle. 891 */ 892 public void onStop() { 893 mCalled = true; 894 } 895 896 public void onLowMemory() { 897 mCalled = true; 898 } 899 900 /** 901 * Called when the view previously created by {@link #onCreateView} has 902 * been detached from the fragment. The next time the fragment needs 903 * to be displayed, a new view will be created. This is called 904 * after {@link #onStop()} and before {@link #onDestroy()}. It is called 905 * <em>regardless</em> of whether {@link #onCreateView} returned a 906 * non-null view. Internally it is called after the view's state has 907 * been saved but before it has been removed from its parent. 908 */ 909 public void onDestroyView() { 910 mCalled = true; 911 } 912 913 /** 914 * Called when the fragment is no longer in use. This is called 915 * after {@link #onStop()} and before {@link #onDetach()}. 916 */ 917 public void onDestroy() { 918 mCalled = true; 919 //Log.v("foo", "onDestroy: mCheckedForLoaderManager=" + mCheckedForLoaderManager 920 // + " mLoaderManager=" + mLoaderManager); 921 if (!mCheckedForLoaderManager) { 922 mCheckedForLoaderManager = true; 923 mLoaderManager = mActivity.getLoaderManager(mIndex, mStarted, false); 924 } 925 if (mLoaderManager != null) { 926 mLoaderManager.doDestroy(); 927 } 928 } 929 930 /** 931 * Called when the fragment is no longer attached to its activity. This 932 * is called after {@link #onDestroy()}. 933 */ 934 public void onDetach() { 935 mCalled = true; 936 } 937 938 /** 939 * Initialize the contents of the Activity's standard options menu. You 940 * should place your menu items in to <var>menu</var>. For this method 941 * to be called, you must have first called {@link #setHasOptionsMenu}. See 942 * {@link Activity#onCreateOptionsMenu(Menu) Activity.onCreateOptionsMenu} 943 * for more information. 944 * 945 * @param menu The options menu in which you place your items. 946 * 947 * @see #setHasOptionsMenu 948 * @see #onPrepareOptionsMenu 949 * @see #onOptionsItemSelected 950 */ 951 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 952 } 953 954 /** 955 * Prepare the Screen's standard options menu to be displayed. This is 956 * called right before the menu is shown, every time it is shown. You can 957 * use this method to efficiently enable/disable items or otherwise 958 * dynamically modify the contents. See 959 * {@link Activity#onPrepareOptionsMenu(Menu) Activity.onPrepareOptionsMenu} 960 * for more information. 961 * 962 * @param menu The options menu as last shown or first initialized by 963 * onCreateOptionsMenu(). 964 * 965 * @see #setHasOptionsMenu 966 * @see #onCreateOptionsMenu 967 */ 968 public void onPrepareOptionsMenu(Menu menu) { 969 } 970 971 /** 972 * This hook is called whenever an item in your options menu is selected. 973 * The default implementation simply returns false to have the normal 974 * processing happen (calling the item's Runnable or sending a message to 975 * its Handler as appropriate). You can use this method for any items 976 * for which you would like to do processing without those other 977 * facilities. 978 * 979 * <p>Derived classes should call through to the base class for it to 980 * perform the default menu handling. 981 * 982 * @param item The menu item that was selected. 983 * 984 * @return boolean Return false to allow normal menu processing to 985 * proceed, true to consume it here. 986 * 987 * @see #onCreateOptionsMenu 988 */ 989 public boolean onOptionsItemSelected(MenuItem item) { 990 return false; 991 } 992 993 /** 994 * This hook is called whenever the options menu is being closed (either by the user canceling 995 * the menu with the back/menu button, or when an item is selected). 996 * 997 * @param menu The options menu as last shown or first initialized by 998 * onCreateOptionsMenu(). 999 */ 1000 public void onOptionsMenuClosed(Menu menu) { 1001 } 1002 1003 /** 1004 * Called when a context menu for the {@code view} is about to be shown. 1005 * Unlike {@link #onCreateOptionsMenu}, this will be called every 1006 * time the context menu is about to be shown and should be populated for 1007 * the view (or item inside the view for {@link AdapterView} subclasses, 1008 * this can be found in the {@code menuInfo})). 1009 * <p> 1010 * Use {@link #onContextItemSelected(android.view.MenuItem)} to know when an 1011 * item has been selected. 1012 * <p> 1013 * The default implementation calls up to 1014 * {@link Activity#onCreateContextMenu Activity.onCreateContextMenu}, though 1015 * you can not call this implementation if you don't want that behavior. 1016 * <p> 1017 * It is not safe to hold onto the context menu after this method returns. 1018 * {@inheritDoc} 1019 */ 1020 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { 1021 getActivity().onCreateContextMenu(menu, v, menuInfo); 1022 } 1023 1024 /** 1025 * Registers a context menu to be shown for the given view (multiple views 1026 * can show the context menu). This method will set the 1027 * {@link OnCreateContextMenuListener} on the view to this fragment, so 1028 * {@link #onCreateContextMenu(ContextMenu, View, ContextMenuInfo)} will be 1029 * called when it is time to show the context menu. 1030 * 1031 * @see #unregisterForContextMenu(View) 1032 * @param view The view that should show a context menu. 1033 */ 1034 public void registerForContextMenu(View view) { 1035 view.setOnCreateContextMenuListener(this); 1036 } 1037 1038 /** 1039 * Prevents a context menu to be shown for the given view. This method will 1040 * remove the {@link OnCreateContextMenuListener} on the view. 1041 * 1042 * @see #registerForContextMenu(View) 1043 * @param view The view that should stop showing a context menu. 1044 */ 1045 public void unregisterForContextMenu(View view) { 1046 view.setOnCreateContextMenuListener(null); 1047 } 1048 1049 /** 1050 * This hook is called whenever an item in a context menu is selected. The 1051 * default implementation simply returns false to have the normal processing 1052 * happen (calling the item's Runnable or sending a message to its Handler 1053 * as appropriate). You can use this method for any items for which you 1054 * would like to do processing without those other facilities. 1055 * <p> 1056 * Use {@link MenuItem#getMenuInfo()} to get extra information set by the 1057 * View that added this menu item. 1058 * <p> 1059 * Derived classes should call through to the base class for it to perform 1060 * the default menu handling. 1061 * 1062 * @param item The context menu item that was selected. 1063 * @return boolean Return false to allow normal context menu processing to 1064 * proceed, true to consume it here. 1065 */ 1066 public boolean onContextItemSelected(MenuItem item) { 1067 return false; 1068 } 1069 1070 void performStop() { 1071 onStop(); 1072 if (mStarted) { 1073 mStarted = false; 1074 if (!mCheckedForLoaderManager) { 1075 mCheckedForLoaderManager = true; 1076 mLoaderManager = mActivity.getLoaderManager(mIndex, mStarted, false); 1077 } 1078 if (mLoaderManager != null) { 1079 if (mActivity == null || !mActivity.mChangingConfigurations) { 1080 mLoaderManager.doStop(); 1081 } else { 1082 mLoaderManager.doRetain(); 1083 } 1084 } 1085 } 1086 } 1087} 1088