Fragment.java revision 811ed1065f39469cf2cf6adba22cab397ed88d5e
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.AttributeSet; 28import android.util.Log; 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.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 /** 499 * Called when a fragment loads an animation. 500 */ 501 public Animatable onCreateAnimatable(int transit, boolean enter, int nextAnim) { 502 return null; 503 } 504 505 /** 506 * Called to do initial creation of a fragment. This is called after 507 * {@link #onAttach(Activity)} and before 508 * {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}. 509 * 510 * <p>Note that this can be called while the fragment's activity is 511 * still in the process of being created. As such, you can not rely 512 * on things like the activity's content view hierarchy being initialized 513 * at this point. If you want to do work once the activity itself is 514 * created, see {@link #onActivityCreated(Bundle)}. 515 * 516 * @param savedInstanceState If the fragment is being re-created from 517 * a previous saved state, this is the state. 518 */ 519 public void onCreate(Bundle savedInstanceState) { 520 mCalled = true; 521 } 522 523 /** 524 * Called to have the fragment instantiate its user interface view. 525 * This is optional, and non-graphical fragments can return null (which 526 * is the default implementation). This will be called between 527 * {@link #onCreate(Bundle)} and {@link #onActivityCreated(Bundle)}. 528 * 529 * <p>If you return a View from here, you will later be called in 530 * {@link #onDestroyView} when the view is being released. 531 * 532 * @param inflater The LayoutInflater object that can be used to inflate 533 * any views in the fragment, 534 * @param container If non-null, this is the parent view that the fragment's 535 * UI should be attached to. The fragment should not add the view itself, 536 * but this can be used to generate the LayoutParams of the view. 537 * @param savedInstanceState If non-null, this fragment is being re-constructed 538 * from a previous saved state as given here. 539 * 540 * @return Return the View for the fragment's UI, or null. 541 */ 542 public View onCreateView(LayoutInflater inflater, ViewGroup container, 543 Bundle savedInstanceState) { 544 return null; 545 } 546 547 public View getView() { 548 return mView; 549 } 550 551 /** 552 * Called when the fragment's activity has been created and this 553 * fragment's view hierarchy instantiated. It can be used to do final 554 * initialization once these pieces are in place, such as retrieving 555 * views or restoring state. It is also useful for fragments that use 556 * {@link #setRetainInstance(boolean)} to retain their instance, 557 * as this callback tells the fragment when it is fully associated with 558 * the new activity instance. This is called after {@link #onCreateView} 559 * and before {@link #onStart()}. 560 * 561 * @param savedInstanceState If the fragment is being re-created from 562 * a previous saved state, this is the state. 563 */ 564 public void onActivityCreated(Bundle savedInstanceState) { 565 mCalled = true; 566 } 567 568 /** 569 * Called when the Fragment is visible to the user. This is generally 570 * tied to {@link Activity#onStart() Activity.onStart} of the containing 571 * Activity's lifecycle. 572 */ 573 public void onStart() { 574 mCalled = true; 575 mStarted = true; 576 if (!mCheckedForLoaderManager) { 577 mCheckedForLoaderManager = true; 578 mLoaderManager = mActivity.getLoaderManager(mIndex, mStarted, false); 579 } 580 if (mLoaderManager != null) { 581 mLoaderManager.doStart(); 582 } 583 } 584 585 /** 586 * Called when the fragment is visible to the user and actively running. 587 * This is generally 588 * tied to {@link Activity#onResume() Activity.onResume} of the containing 589 * Activity's lifecycle. 590 */ 591 public void onResume() { 592 mCalled = true; 593 } 594 595 public void onSaveInstanceState(Bundle outState) { 596 } 597 598 public void onConfigurationChanged(Configuration newConfig) { 599 mCalled = true; 600 } 601 602 /** 603 * Called when the Fragment is no longer resumed. This is generally 604 * tied to {@link Activity#onPause() Activity.onPause} of the containing 605 * Activity's lifecycle. 606 */ 607 public void onPause() { 608 mCalled = true; 609 } 610 611 /** 612 * Called when the Fragment is no longer started. This is generally 613 * tied to {@link Activity#onStop() Activity.onStop} of the containing 614 * Activity's lifecycle. 615 */ 616 public void onStop() { 617 mCalled = true; 618 } 619 620 public void onLowMemory() { 621 mCalled = true; 622 } 623 624 /** 625 * Called when the view previously created by {@link #onCreateView} has 626 * been detached from the fragment. The next time the fragment needs 627 * to be displayed, a new view will be created. This is called 628 * after {@link #onStop()} and before {@link #onDestroy()}; it is only 629 * called if {@link #onCreateView} returns a non-null View. 630 */ 631 public void onDestroyView() { 632 mCalled = true; 633 } 634 635 /** 636 * Called when the fragment is no longer in use. This is called 637 * after {@link #onStop()} and before {@link #onDetach()}. 638 */ 639 public void onDestroy() { 640 mCalled = true; 641 //Log.v("foo", "onDestroy: mCheckedForLoaderManager=" + mCheckedForLoaderManager 642 // + " mLoaderManager=" + mLoaderManager); 643 if (!mCheckedForLoaderManager) { 644 mCheckedForLoaderManager = true; 645 mLoaderManager = mActivity.getLoaderManager(mIndex, mStarted, false); 646 } 647 if (mLoaderManager != null) { 648 mLoaderManager.doDestroy(); 649 } 650 } 651 652 /** 653 * Called when the fragment is no longer attached to its activity. This 654 * is called after {@link #onDestroy()}. 655 */ 656 public void onDetach() { 657 mCalled = true; 658 } 659 660 /** 661 * Initialize the contents of the Activity's standard options menu. You 662 * should place your menu items in to <var>menu</var>. For this method 663 * to be called, you must have first called {@link #setHasOptionsMenu}. See 664 * {@link Activity#onCreateOptionsMenu(Menu) Activity.onCreateOptionsMenu} 665 * for more information. 666 * 667 * @param menu The options menu in which you place your items. 668 * 669 * @see #setHasOptionsMenu 670 * @see #onPrepareOptionsMenu 671 * @see #onOptionsItemSelected 672 */ 673 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 674 } 675 676 /** 677 * Prepare the Screen's standard options menu to be displayed. This is 678 * called right before the menu is shown, every time it is shown. You can 679 * use this method to efficiently enable/disable items or otherwise 680 * dynamically modify the contents. See 681 * {@link Activity#onPrepareOptionsMenu(Menu) Activity.onPrepareOptionsMenu} 682 * for more information. 683 * 684 * @param menu The options menu as last shown or first initialized by 685 * onCreateOptionsMenu(). 686 * 687 * @see #setHasOptionsMenu 688 * @see #onCreateOptionsMenu 689 */ 690 public void onPrepareOptionsMenu(Menu menu) { 691 } 692 693 /** 694 * This hook is called whenever an item in your options menu is selected. 695 * The default implementation simply returns false to have the normal 696 * processing happen (calling the item's Runnable or sending a message to 697 * its Handler as appropriate). You can use this method for any items 698 * for which you would like to do processing without those other 699 * facilities. 700 * 701 * <p>Derived classes should call through to the base class for it to 702 * perform the default menu handling. 703 * 704 * @param item The menu item that was selected. 705 * 706 * @return boolean Return false to allow normal menu processing to 707 * proceed, true to consume it here. 708 * 709 * @see #onCreateOptionsMenu 710 */ 711 public boolean onOptionsItemSelected(MenuItem item) { 712 return false; 713 } 714 715 /** 716 * This hook is called whenever the options menu is being closed (either by the user canceling 717 * the menu with the back/menu button, or when an item is selected). 718 * 719 * @param menu The options menu as last shown or first initialized by 720 * onCreateOptionsMenu(). 721 */ 722 public void onOptionsMenuClosed(Menu menu) { 723 } 724 725 /** 726 * Called when a context menu for the {@code view} is about to be shown. 727 * Unlike {@link #onCreateOptionsMenu}, this will be called every 728 * time the context menu is about to be shown and should be populated for 729 * the view (or item inside the view for {@link AdapterView} subclasses, 730 * this can be found in the {@code menuInfo})). 731 * <p> 732 * Use {@link #onContextItemSelected(android.view.MenuItem)} to know when an 733 * item has been selected. 734 * <p> 735 * The default implementation calls up to 736 * {@link Activity#onCreateContextMenu Activity.onCreateContextMenu}, though 737 * you can not call this implementation if you don't want that behavior. 738 * <p> 739 * It is not safe to hold onto the context menu after this method returns. 740 * {@inheritDoc} 741 */ 742 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { 743 getActivity().onCreateContextMenu(menu, v, menuInfo); 744 } 745 746 /** 747 * Registers a context menu to be shown for the given view (multiple views 748 * can show the context menu). This method will set the 749 * {@link OnCreateContextMenuListener} on the view to this fragment, so 750 * {@link #onCreateContextMenu(ContextMenu, View, ContextMenuInfo)} will be 751 * called when it is time to show the context menu. 752 * 753 * @see #unregisterForContextMenu(View) 754 * @param view The view that should show a context menu. 755 */ 756 public void registerForContextMenu(View view) { 757 view.setOnCreateContextMenuListener(this); 758 } 759 760 /** 761 * Prevents a context menu to be shown for the given view. This method will 762 * remove the {@link OnCreateContextMenuListener} on the view. 763 * 764 * @see #registerForContextMenu(View) 765 * @param view The view that should stop showing a context menu. 766 */ 767 public void unregisterForContextMenu(View view) { 768 view.setOnCreateContextMenuListener(null); 769 } 770 771 /** 772 * This hook is called whenever an item in a context menu is selected. The 773 * default implementation simply returns false to have the normal processing 774 * happen (calling the item's Runnable or sending a message to its Handler 775 * as appropriate). You can use this method for any items for which you 776 * would like to do processing without those other facilities. 777 * <p> 778 * Use {@link MenuItem#getMenuInfo()} to get extra information set by the 779 * View that added this menu item. 780 * <p> 781 * Derived classes should call through to the base class for it to perform 782 * the default menu handling. 783 * 784 * @param item The context menu item that was selected. 785 * @return boolean Return false to allow normal context menu processing to 786 * proceed, true to consume it here. 787 */ 788 public boolean onContextItemSelected(MenuItem item) { 789 return false; 790 } 791 792 void performStop() { 793 onStop(); 794 if (mStarted) { 795 mStarted = false; 796 if (!mCheckedForLoaderManager) { 797 mCheckedForLoaderManager = true; 798 mLoaderManager = mActivity.getLoaderManager(mIndex, mStarted, false); 799 } 800 if (mLoaderManager != null) { 801 if (mActivity == null || !mActivity.mChangingConfigurations) { 802 mLoaderManager.doStop(); 803 } else { 804 mLoaderManager.doRetain(); 805 } 806 } 807 } 808 } 809} 810