Fragment.java revision 5e0d59547c4042037e23a42ba4e2521721e9c7d3
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.content.ComponentCallbacks; 20import android.content.Context; 21import android.content.Intent; 22import android.content.res.Configuration; 23import android.os.Bundle; 24import android.os.Parcel; 25import android.os.Parcelable; 26import android.util.AttributeSet; 27import android.util.Log; 28import android.util.SparseArray; 29import android.view.ContextMenu; 30import android.view.LayoutInflater; 31import android.view.Menu; 32import android.view.MenuInflater; 33import android.view.MenuItem; 34import android.view.View; 35import android.view.ViewGroup; 36import android.view.ContextMenu.ContextMenuInfo; 37import android.view.View.OnCreateContextMenuListener; 38import android.view.animation.Animation; 39import android.widget.AdapterView; 40 41import java.lang.reflect.InvocationTargetException; 42import java.util.HashMap; 43 44final class FragmentState implements Parcelable { 45 static final String VIEW_STATE_TAG = "android:view_state"; 46 47 final String mClassName; 48 final int mIndex; 49 final boolean mFromLayout; 50 final int mFragmentId; 51 final int mContainerId; 52 final String mTag; 53 final boolean mRetainInstance; 54 55 Bundle mSavedFragmentState; 56 57 Fragment mInstance; 58 59 public FragmentState(Fragment frag) { 60 mClassName = frag.getClass().getName(); 61 mIndex = frag.mIndex; 62 mFromLayout = frag.mFromLayout; 63 mFragmentId = frag.mFragmentId; 64 mContainerId = frag.mContainerId; 65 mTag = frag.mTag; 66 mRetainInstance = frag.mRetainInstance; 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 mSavedFragmentState = in.readBundle(); 78 } 79 80 public Fragment instantiate(Activity activity) { 81 if (mInstance != null) { 82 return mInstance; 83 } 84 85 try { 86 mInstance = Fragment.instantiate(activity, mClassName); 87 } catch (Exception e) { 88 throw new RuntimeException("Unable to restore fragment " + mClassName, e); 89 } 90 91 if (mSavedFragmentState != null) { 92 mSavedFragmentState.setClassLoader(activity.getClassLoader()); 93 mInstance.mSavedFragmentState = mSavedFragmentState; 94 mInstance.mSavedViewState 95 = mSavedFragmentState.getSparseParcelableArray(VIEW_STATE_TAG); 96 } 97 mInstance.setIndex(mIndex); 98 mInstance.mFromLayout = mFromLayout; 99 mInstance.mFragmentId = mFragmentId; 100 mInstance.mContainerId = mContainerId; 101 mInstance.mTag = mTag; 102 mInstance.mRetainInstance = mRetainInstance; 103 104 return mInstance; 105 } 106 107 public int describeContents() { 108 return 0; 109 } 110 111 public void writeToParcel(Parcel dest, int flags) { 112 dest.writeString(mClassName); 113 dest.writeInt(mIndex); 114 dest.writeInt(mFromLayout ? 1 : 0); 115 dest.writeInt(mFragmentId); 116 dest.writeInt(mContainerId); 117 dest.writeString(mTag); 118 dest.writeInt(mRetainInstance ? 1 : 0); 119 dest.writeBundle(mSavedFragmentState); 120 } 121 122 public static final Parcelable.Creator<FragmentState> CREATOR 123 = new Parcelable.Creator<FragmentState>() { 124 public FragmentState createFromParcel(Parcel in) { 125 return new FragmentState(in); 126 } 127 128 public FragmentState[] newArray(int size) { 129 return new FragmentState[size]; 130 } 131 }; 132} 133 134/** 135 * A Fragment is a piece of an application's user interface or behavior 136 * that can be placed in an {@link Activity}. 137 */ 138public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener { 139 private static final HashMap<String, Class<?>> sClassMap = 140 new HashMap<String, Class<?>>(); 141 142 static final int INITIALIZING = 0; // Not yet created. 143 static final int CREATED = 1; // Created. 144 static final int ACTIVITY_CREATED = 2; // The activity has finished its creation. 145 static final int STARTED = 3; // Created and started, not resumed. 146 static final int RESUMED = 4; // Created started and resumed. 147 148 int mState = INITIALIZING; 149 150 // When instantiated from saved state, this is the saved state. 151 Bundle mSavedFragmentState; 152 SparseArray<Parcelable> mSavedViewState; 153 154 // Index into active fragment array. 155 int mIndex = -1; 156 157 // Internal unique name for this fragment; 158 String mWho; 159 160 // True if the fragment is in the list of added fragments. 161 boolean mAdded; 162 163 // True if the fragment is in the resumed state. 164 boolean mResumed; 165 166 // Set to true if this fragment was instantiated from a layout file. 167 boolean mFromLayout; 168 169 // Number of active back stack entries this fragment is in. 170 int mBackStackNesting; 171 172 // Set as soon as a fragment is added to a transaction (or removed), 173 // to be able to do validation. 174 Activity mImmediateActivity; 175 176 // Activity this fragment is attached to. 177 Activity mActivity; 178 179 // The optional identifier for this fragment -- either the container ID if it 180 // was dynamically added to the view hierarchy, or the ID supplied in 181 // layout. 182 int mFragmentId; 183 184 // When a fragment is being dynamically added to the view hierarchy, this 185 // is the identifier of the parent container it is being added to. 186 int mContainerId; 187 188 // The optional named tag for this fragment -- usually used to find 189 // fragments that are not part of the layout. 190 String mTag; 191 192 // Set to true when the app has requested that this fragment be hidden 193 // from the user. 194 boolean mHidden; 195 196 // If set this fragment would like its instance retained across 197 // configuration changes. 198 boolean mRetainInstance; 199 200 // If set this fragment is being retained across the current config change. 201 boolean mRetaining; 202 203 // If set this fragment has menu items to contribute. 204 boolean mHasMenu; 205 206 // Used to verify that subclasses call through to super class. 207 boolean mCalled; 208 209 // If app has requested a specific animation, this is the one to use. 210 int mNextAnim; 211 212 // The parent container of the fragment after dynamically added to UI. 213 ViewGroup mContainer; 214 215 // The View generated for this fragment. 216 View mView; 217 218 LoaderManagerImpl mLoaderManager; 219 boolean mStarted; 220 boolean mCheckedForLoaderManager; 221 222 /** 223 * Default constructor. <strong>Every</string> fragment must have an 224 * empty constructor, so it can be instantiated when restoring its 225 * activity's state. It is strongly recommended that subclasses do not 226 * have other constructors with parameters, since these constructors 227 * will not be called when the fragment is re-instantiated; instead, 228 * retrieve such parameters from the activity in {@link #onAttach(Activity)}. 229 */ 230 public Fragment() { 231 } 232 233 /** 234 * Create a new instance of a Fragment with the given class name. This is 235 * the same as calling its empty constructor. 236 * 237 * @param context The calling context being used to instantiate the fragment. 238 * This is currently just used to get its ClassLoader. 239 * @param fname The class name of the fragment to instantiate. 240 * @return Returns a new fragment instance. 241 * @throws NoSuchMethodException The fragment does not have an empty constructor. 242 * @throws ClassNotFoundException The fragment class does not exist. 243 * @throws IllegalArgumentException Bad arguments supplied to fragment class 244 * constructor (should not happen). 245 * @throws InstantiationException Caller does not have permission to instantiate 246 * the fragment (for example its constructor is not public). 247 * @throws IllegalAccessException Caller does not have permission to access 248 * the given fragment class. 249 * @throws InvocationTargetException Failure running the fragment's constructor. 250 */ 251 public static Fragment instantiate(Context context, String fname) 252 throws NoSuchMethodException, ClassNotFoundException, 253 IllegalArgumentException, InstantiationException, 254 IllegalAccessException, InvocationTargetException { 255 Class<?> clazz = sClassMap.get(fname); 256 257 if (clazz == null) { 258 // Class not found in the cache, see if it's real, and try to add it 259 clazz = context.getClassLoader().loadClass(fname); 260 sClassMap.put(fname, clazz); 261 } 262 return (Fragment)clazz.newInstance(); 263 } 264 265 void restoreViewState() { 266 if (mSavedViewState != null) { 267 mView.restoreHierarchyState(mSavedViewState); 268 mSavedViewState = null; 269 } 270 } 271 272 void setIndex(int index) { 273 mIndex = index; 274 mWho = "android:fragment:" + mIndex; 275 } 276 277 void clearIndex() { 278 mIndex = -1; 279 mWho = null; 280 } 281 282 /** 283 * Subclasses can not override equals(). 284 */ 285 @Override final public boolean equals(Object o) { 286 return super.equals(o); 287 } 288 289 /** 290 * Subclasses can not override hashCode(). 291 */ 292 @Override final public int hashCode() { 293 return super.hashCode(); 294 } 295 296 @Override 297 public String toString() { 298 StringBuilder sb = new StringBuilder(128); 299 sb.append("Fragment{"); 300 sb.append(Integer.toHexString(System.identityHashCode(this))); 301 if (mIndex >= 0) { 302 sb.append(" #"); 303 sb.append(mIndex); 304 } 305 if (mFragmentId != 0) { 306 sb.append(" id=0x"); 307 sb.append(Integer.toHexString(mFragmentId)); 308 } 309 if (mTag != null) { 310 sb.append(" "); 311 sb.append(mTag); 312 } 313 sb.append('}'); 314 return sb.toString(); 315 } 316 317 /** 318 * Return the identifier this fragment is known by. This is either 319 * the android:id value supplied in a layout or the container view ID 320 * supplied when adding the fragment. 321 */ 322 final public int getId() { 323 return mFragmentId; 324 } 325 326 /** 327 * Get the tag name of the fragment, if specified. 328 */ 329 final public String getTag() { 330 return mTag; 331 } 332 333 /** 334 * Return the Activity this fragment is currently associated with. 335 */ 336 final public Activity getActivity() { 337 return mActivity; 338 } 339 340 /** 341 * Return true if the fragment is currently added to its activity. 342 */ 343 final public boolean isAdded() { 344 return mActivity != null && mActivity.mFragments.mAdded.contains(this); 345 } 346 347 /** 348 * Return true if the fragment is in the resumed state. This is true 349 * for the duration of {@link #onResume()} and {@link #onPause()} as well. 350 */ 351 final public boolean isResumed() { 352 return mResumed; 353 } 354 355 /** 356 * Return true if the fragment is currently visible to the user. This means 357 * it: (1) has been added, (2) has its view attached to the window, and 358 * (3) is not hidden. 359 */ 360 final public boolean isVisible() { 361 return isAdded() && !isHidden() && mView != null 362 && mView.getWindowToken() != null && mView.getVisibility() == View.VISIBLE; 363 } 364 365 /** 366 * Return true if the fragment has been hidden. By default fragments 367 * are shown. You can find out about changes to this state with 368 * {@link #onHiddenChanged}. Note that the hidden state is orthogonal 369 * to other states -- that is, to be visible to the user, a fragment 370 * must be both started and not hidden. 371 */ 372 final public boolean isHidden() { 373 return mHidden; 374 } 375 376 /** 377 * Called when the hidden state (as returned by {@link #isHidden()} of 378 * the fragment has changed. Fragments start out not hidden; this will 379 * be called whenever the fragment changes state from that. 380 * @param hidden True if the fragment is now hidden, false if it is not 381 * visible. 382 */ 383 public void onHiddenChanged(boolean hidden) { 384 } 385 386 /** 387 * Control whether a fragment instance is retained across Activity 388 * re-creation (such as from a configuration change). This can only 389 * be used with fragments not in the back stack. If set, the fragment 390 * lifecycle will be slightly different when an activity is recreated: 391 * <ul> 392 * <li> {@link #onDestroy()} will not be called (but {@link #onDetach()} still 393 * will be, because the fragment is being detached from its current activity). 394 * <li> {@link #onCreate(Bundle)} will not be called since the fragment 395 * is not being re-created. 396 * <li> {@link #onAttach(Activity)} and {@link #onActivityCreated(Bundle)} <b>will</b> 397 * still be called. 398 * </ul> 399 */ 400 public void setRetainInstance(boolean retain) { 401 mRetainInstance = retain; 402 } 403 404 final public boolean getRetainInstance() { 405 return mRetainInstance; 406 } 407 408 /** 409 * Report that this fragment would like to participate in populating 410 * the options menu by receiving a call to {@link #onCreateOptionsMenu} 411 * and related methods. 412 * 413 * @param hasMenu If true, the fragment has menu items to contribute. 414 */ 415 public void setHasOptionsMenu(boolean hasMenu) { 416 if (mHasMenu != hasMenu) { 417 mHasMenu = hasMenu; 418 if (isAdded() && !isHidden()) { 419 mActivity.invalidateOptionsMenu(); 420 } 421 } 422 } 423 424 /** 425 * Return the LoaderManager for this fragment, creating it if needed. 426 */ 427 public LoaderManager getLoaderManager() { 428 if (mLoaderManager != null) { 429 return mLoaderManager; 430 } 431 mCheckedForLoaderManager = true; 432 mLoaderManager = mActivity.getLoaderManager(mIndex, mStarted, true); 433 return mLoaderManager; 434 } 435 436 /** 437 * Call {@link Activity#startActivity(Intent)} on the fragment's 438 * containing Activity. 439 */ 440 public void startActivity(Intent intent) { 441 mActivity.startActivityFromFragment(this, intent, -1); 442 } 443 444 /** 445 * Call {@link Activity#startActivityForResult(Intent, int)} on the fragment's 446 * containing Activity. 447 */ 448 public void startActivityForResult(Intent intent, int requestCode) { 449 mActivity.startActivityFromFragment(this, intent, requestCode); 450 } 451 452 /** 453 * Receive the result from a previous call to 454 * {@link #startActivityForResult(Intent, int)}. This follows the 455 * related Activity API as described there in 456 * {@link Activity#onActivityResult(int, int, Intent)}. 457 * 458 * @param requestCode The integer request code originally supplied to 459 * startActivityForResult(), allowing you to identify who this 460 * result came from. 461 * @param resultCode The integer result code returned by the child activity 462 * through its setResult(). 463 * @param data An Intent, which can return result data to the caller 464 * (various data can be attached to Intent "extras"). 465 */ 466 public void onActivityResult(int requestCode, int resultCode, Intent data) { 467 } 468 469 /** 470 * Called when a fragment is being created as part of a view layout 471 * inflation, typically from setting the content view of an activity. This 472 * will be called both the first time the fragment is created, as well 473 * later when it is being re-created from its saved state (which is also 474 * given here). 475 * 476 * XXX This is kind-of yucky... maybe we could just supply the 477 * AttributeSet to onCreate()? 478 * 479 * @param activity The Activity that is inflating the fragment. 480 * @param attrs The attributes at the tag where the fragment is 481 * being created. 482 * @param savedInstanceState If the fragment is being re-created from 483 * a previous saved state, this is the state. 484 */ 485 public void onInflate(Activity activity, AttributeSet attrs, 486 Bundle savedInstanceState) { 487 mCalled = true; 488 } 489 490 /** 491 * Called when a fragment is first attached to its activity. 492 * {@link #onCreate(Bundle)} will be called after this. 493 */ 494 public void onAttach(Activity activity) { 495 mCalled = true; 496 } 497 498 public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) { 499 return null; 500 } 501 502 /** 503 * Called to do initial creation of a fragment. This is called after 504 * {@link #onAttach(Activity)} and before 505 * {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}. 506 * 507 * <p>Note that this can be called while the fragment's activity is 508 * still in the process of being created. As such, you can not rely 509 * on things like the activity's content view hierarchy being initialized 510 * at this point. If you want to do work once the activity itself is 511 * created, see {@link #onActivityCreated(Bundle)}. 512 * 513 * @param savedInstanceState If the fragment is being re-created from 514 * a previous saved state, this is the state. 515 */ 516 public void onCreate(Bundle savedInstanceState) { 517 mCalled = true; 518 } 519 520 /** 521 * Called to have the fragment instantiate its user interface view. 522 * This is optional, and non-graphical fragments can return null (which 523 * is the default implementation). This will be called between 524 * {@link #onCreate(Bundle)} and {@link #onActivityCreated(Bundle)}. 525 * 526 * <p>If you return a View from here, you will later be called in 527 * {@link #onDestroyView} when the view is being released. 528 * 529 * @param inflater The LayoutInflater object that can be used to inflate 530 * any views in the fragment, 531 * @param container If non-null, this is the parent view that the fragment's 532 * UI should be attached to. The fragment should not add the view itself, 533 * but this can be used to generate the LayoutParams of the view. 534 * @param savedInstanceState If non-null, this fragment is being re-constructed 535 * from a previous saved state as given here. 536 * 537 * @return Return the View for the fragment's UI, or null. 538 */ 539 public View onCreateView(LayoutInflater inflater, ViewGroup container, 540 Bundle savedInstanceState) { 541 return null; 542 } 543 544 public View getView() { 545 return mView; 546 } 547 548 /** 549 * Called when the fragment's activity has been created and this 550 * fragment's view hierarchy instantiated. It can be used to do final 551 * initialization once these pieces are in place, such as retrieving 552 * views or restoring state. It is also useful for fragments that use 553 * {@link #setRetainInstance(boolean)} to retain their instance, 554 * as this callback tells the fragment when it is fully associated with 555 * the new activity instance. This is called after {@link #onCreateView} 556 * and before {@link #onStart()}. 557 * 558 * @param savedInstanceState If the fragment is being re-created from 559 * a previous saved state, this is the state. 560 */ 561 public void onActivityCreated(Bundle savedInstanceState) { 562 mCalled = true; 563 } 564 565 /** 566 * Called when the Fragment is visible to the user. This is generally 567 * tied to {@link Activity#onStart() Activity.onStart} of the containing 568 * Activity's lifecycle. 569 */ 570 public void onStart() { 571 mCalled = true; 572 mStarted = true; 573 if (!mCheckedForLoaderManager) { 574 mCheckedForLoaderManager = true; 575 mLoaderManager = mActivity.getLoaderManager(mIndex, mStarted, false); 576 } 577 if (mLoaderManager != null) { 578 mLoaderManager.doStart(); 579 } 580 } 581 582 /** 583 * Called when the fragment is visible to the user and actively running. 584 * This is generally 585 * tied to {@link Activity#onResume() Activity.onResume} of the containing 586 * Activity's lifecycle. 587 */ 588 public void onResume() { 589 mCalled = true; 590 } 591 592 public void onSaveInstanceState(Bundle outState) { 593 } 594 595 public void onConfigurationChanged(Configuration newConfig) { 596 mCalled = true; 597 } 598 599 /** 600 * Called when the Fragment is no longer resumed. This is generally 601 * tied to {@link Activity#onPause() Activity.onPause} of the containing 602 * Activity's lifecycle. 603 */ 604 public void onPause() { 605 mCalled = true; 606 } 607 608 /** 609 * Called when the Fragment is no longer started. This is generally 610 * tied to {@link Activity#onStop() Activity.onStop} of the containing 611 * Activity's lifecycle. 612 */ 613 public void onStop() { 614 mCalled = true; 615 } 616 617 public void onLowMemory() { 618 mCalled = true; 619 } 620 621 /** 622 * Called when the view previously created by {@link #onCreateView} has 623 * been detached from the fragment. The next time the fragment needs 624 * to be displayed, a new view will be created. This is called 625 * after {@link #onStop()} and before {@link #onDestroy()}; it is only 626 * called if {@link #onCreateView} returns a non-null View. 627 */ 628 public void onDestroyView() { 629 mCalled = true; 630 } 631 632 /** 633 * Called when the fragment is no longer in use. This is called 634 * after {@link #onStop()} and before {@link #onDetach()}. 635 */ 636 public void onDestroy() { 637 mCalled = true; 638 //Log.v("foo", "onDestroy: mCheckedForLoaderManager=" + mCheckedForLoaderManager 639 // + " mLoaderManager=" + mLoaderManager); 640 if (!mCheckedForLoaderManager) { 641 mCheckedForLoaderManager = true; 642 mLoaderManager = mActivity.getLoaderManager(mIndex, mStarted, false); 643 } 644 if (mLoaderManager != null) { 645 mLoaderManager.doDestroy(); 646 } 647 } 648 649 /** 650 * Called when the fragment is no longer attached to its activity. This 651 * is called after {@link #onDestroy()}. 652 */ 653 public void onDetach() { 654 mCalled = true; 655 } 656 657 /** 658 * Initialize the contents of the Activity's standard options menu. You 659 * should place your menu items in to <var>menu</var>. For this method 660 * to be called, you must have first called {@link #setHasOptionsMenu}. See 661 * {@link Activity#onCreateOptionsMenu(Menu) Activity.onCreateOptionsMenu} 662 * for more information. 663 * 664 * @param menu The options menu in which you place your items. 665 * 666 * @see #setHasOptionsMenu 667 * @see #onPrepareOptionsMenu 668 * @see #onOptionsItemSelected 669 */ 670 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 671 } 672 673 /** 674 * Prepare the Screen's standard options menu to be displayed. This is 675 * called right before the menu is shown, every time it is shown. You can 676 * use this method to efficiently enable/disable items or otherwise 677 * dynamically modify the contents. See 678 * {@link Activity#onPrepareOptionsMenu(Menu) Activity.onPrepareOptionsMenu} 679 * for more information. 680 * 681 * @param menu The options menu as last shown or first initialized by 682 * onCreateOptionsMenu(). 683 * 684 * @see #setHasOptionsMenu 685 * @see #onCreateOptionsMenu 686 */ 687 public void onPrepareOptionsMenu(Menu menu) { 688 } 689 690 /** 691 * This hook is called whenever an item in your options menu is selected. 692 * The default implementation simply returns false to have the normal 693 * processing happen (calling the item's Runnable or sending a message to 694 * its Handler as appropriate). You can use this method for any items 695 * for which you would like to do processing without those other 696 * facilities. 697 * 698 * <p>Derived classes should call through to the base class for it to 699 * perform the default menu handling. 700 * 701 * @param item The menu item that was selected. 702 * 703 * @return boolean Return false to allow normal menu processing to 704 * proceed, true to consume it here. 705 * 706 * @see #onCreateOptionsMenu 707 */ 708 public boolean onOptionsItemSelected(MenuItem item) { 709 return false; 710 } 711 712 /** 713 * This hook is called whenever the options menu is being closed (either by the user canceling 714 * the menu with the back/menu button, or when an item is selected). 715 * 716 * @param menu The options menu as last shown or first initialized by 717 * onCreateOptionsMenu(). 718 */ 719 public void onOptionsMenuClosed(Menu menu) { 720 } 721 722 /** 723 * Called when a context menu for the {@code view} is about to be shown. 724 * Unlike {@link #onCreateOptionsMenu}, this will be called every 725 * time the context menu is about to be shown and should be populated for 726 * the view (or item inside the view for {@link AdapterView} subclasses, 727 * this can be found in the {@code menuInfo})). 728 * <p> 729 * Use {@link #onContextItemSelected(android.view.MenuItem)} to know when an 730 * item has been selected. 731 * <p> 732 * The default implementation calls up to 733 * {@link Activity#onCreateContextMenu Activity.onCreateContextMenu}, though 734 * you can not call this implementation if you don't want that behavior. 735 * <p> 736 * It is not safe to hold onto the context menu after this method returns. 737 * {@inheritDoc} 738 */ 739 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { 740 getActivity().onCreateContextMenu(menu, v, menuInfo); 741 } 742 743 /** 744 * Registers a context menu to be shown for the given view (multiple views 745 * can show the context menu). This method will set the 746 * {@link OnCreateContextMenuListener} on the view to this fragment, so 747 * {@link #onCreateContextMenu(ContextMenu, View, ContextMenuInfo)} will be 748 * called when it is time to show the context menu. 749 * 750 * @see #unregisterForContextMenu(View) 751 * @param view The view that should show a context menu. 752 */ 753 public void registerForContextMenu(View view) { 754 view.setOnCreateContextMenuListener(this); 755 } 756 757 /** 758 * Prevents a context menu to be shown for the given view. This method will 759 * remove the {@link OnCreateContextMenuListener} on the view. 760 * 761 * @see #registerForContextMenu(View) 762 * @param view The view that should stop showing a context menu. 763 */ 764 public void unregisterForContextMenu(View view) { 765 view.setOnCreateContextMenuListener(null); 766 } 767 768 /** 769 * This hook is called whenever an item in a context menu is selected. The 770 * default implementation simply returns false to have the normal processing 771 * happen (calling the item's Runnable or sending a message to its Handler 772 * as appropriate). You can use this method for any items for which you 773 * would like to do processing without those other facilities. 774 * <p> 775 * Use {@link MenuItem#getMenuInfo()} to get extra information set by the 776 * View that added this menu item. 777 * <p> 778 * Derived classes should call through to the base class for it to perform 779 * the default menu handling. 780 * 781 * @param item The context menu item that was selected. 782 * @return boolean Return false to allow normal context menu processing to 783 * proceed, true to consume it here. 784 */ 785 public boolean onContextItemSelected(MenuItem item) { 786 return false; 787 } 788 789 void performStop() { 790 onStop(); 791 if (mStarted) { 792 mStarted = false; 793 if (!mCheckedForLoaderManager) { 794 mCheckedForLoaderManager = true; 795 mLoaderManager = mActivity.getLoaderManager(mIndex, mStarted, false); 796 } 797 if (mLoaderManager != null) { 798 if (mActivity == null || !mActivity.mChangingConfigurations) { 799 mLoaderManager.doStop(); 800 } else { 801 mLoaderManager.doRetain(); 802 } 803 } 804 } 805 } 806} 807