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