Applications should generally not implement a constructor. The
- * first place application code an run where the fragment is ready to
- * be used is in {@link #onAttach(Activity)}, the point where the fragment
- * is actually associated with its activity. Some applications may also
- * want to implement {@link #onInflate} to retrieve attributes from a
- * layout resource, though should take care here because this happens for
- * the fragment is attached to its activity.
- */
- public Fragment() {
- }
-
- /**
- * Like {@link #instantiate(Context, String, Bundle)} but with a null
- * argument Bundle.
- */
- public static Fragment instantiate(Context context, String fname) {
- return instantiate(context, fname, null);
- }
-
- /**
- * Create a new instance of a Fragment with the given class name. This is
- * the same as calling its empty constructor.
- *
- * @param context The calling context being used to instantiate the fragment.
- * This is currently just used to get its ClassLoader.
- * @param fname The class name of the fragment to instantiate.
- * @param args Bundle of arguments to supply to the fragment, which it
- * can retrieve with {@link #getArguments()}. May be null.
- * @return Returns a new fragment instance.
- * @throws InstantiationException If there is a failure in instantiating
- * the given fragment class. This is a runtime exception; it is not
- * normally expected to happen.
- */
- public static Fragment instantiate(Context context, String fname, Bundle args) {
- try {
- Class> clazz = sClassMap.get(fname);
- if (clazz == null) {
- // Class not found in the cache, see if it's real, and try to add it
- clazz = context.getClassLoader().loadClass(fname);
- sClassMap.put(fname, clazz);
- }
- Fragment f = (Fragment)clazz.newInstance();
- if (args != null) {
- args.setClassLoader(f.getClass().getClassLoader());
- f.mArguments = args;
- }
- return f;
- } catch (ClassNotFoundException e) {
- throw new InstantiationException("Unable to instantiate fragment " + fname
- + ": make sure class name exists, is public, and has an"
- + " empty constructor that is public", e);
- } catch (java.lang.InstantiationException e) {
- throw new InstantiationException("Unable to instantiate fragment " + fname
- + ": make sure class name exists, is public, and has an"
- + " empty constructor that is public", e);
- } catch (IllegalAccessException e) {
- throw new InstantiationException("Unable to instantiate fragment " + fname
- + ": make sure class name exists, is public, and has an"
- + " empty constructor that is public", e);
- }
- }
-
- final void restoreViewState() {
- if (mSavedViewState != null) {
- mInnerView.restoreHierarchyState(mSavedViewState);
- mSavedViewState = null;
- }
- }
-
- final void setIndex(int index) {
- mIndex = index;
- mWho = "android:fragment:" + mIndex;
- }
-
- final boolean isInBackStack() {
- return mBackStackNesting > 0;
- }
-
- /**
- * Subclasses can not override equals().
- */
- @Override final public boolean equals(Object o) {
- return super.equals(o);
- }
-
- /**
- * Subclasses can not override hashCode().
- */
- @Override final public int hashCode() {
- return super.hashCode();
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder(128);
- DebugUtils.buildShortClassTag(this, sb);
- if (mIndex >= 0) {
- sb.append(" #");
- sb.append(mIndex);
- }
- if (mFragmentId != 0) {
- sb.append(" id=0x");
- sb.append(Integer.toHexString(mFragmentId));
- }
- if (mTag != null) {
- sb.append(" ");
- sb.append(mTag);
- }
- sb.append('}');
- return sb.toString();
- }
-
- /**
- * Return the identifier this fragment is known by. This is either
- * the android:id value supplied in a layout or the container view ID
- * supplied when adding the fragment.
- */
- final public int getId() {
- return mFragmentId;
- }
-
- /**
- * Get the tag name of the fragment, if specified.
- */
- final public String getTag() {
- return mTag;
- }
-
- /**
- * Supply the construction arguments for this fragment. This can only
- * be called before the fragment has been attached to its activity; that
- * is, you should call it immediately after constructing the fragment. The
- * arguments supplied here will be retained across fragment destroy and
- * creation.
- */
- public void setArguments(Bundle args) {
- if (mIndex >= 0) {
- throw new IllegalStateException("Fragment already active");
- }
- mArguments = args;
- }
-
- /**
- * Return the arguments supplied when the fragment was instantiated,
- * if any.
- */
- final public Bundle getArguments() {
- return mArguments;
- }
-
- /**
- * Set the initial saved state that this Fragment should restore itself
- * from when first being constructed, as returned by
- * {@link FragmentManager#saveFragmentInstanceState(Fragment)
- * FragmentManager.saveFragmentInstanceState}.
- *
- * @param state The state the fragment should be restored from.
- */
- public void setInitialSavedState(SavedState state) {
- if (mIndex >= 0) {
- throw new IllegalStateException("Fragment already active");
- }
- mSavedFragmentState = state != null && state.mState != null
- ? state.mState : null;
- }
-
- /**
- * Optional target for this fragment. This may be used, for example,
- * if this fragment is being started by another, and when done wants to
- * give a result back to the first. The target set here is retained
- * across instances via {@link FragmentManager#putFragment
- * FragmentManager.putFragment()}.
- *
- * @param fragment The fragment that is the target of this one.
- * @param requestCode Optional request code, for convenience if you
- * are going to call back with {@link #onActivityResult(int, int, Intent)}.
- */
- public void setTargetFragment(Fragment fragment, int requestCode) {
- mTarget = fragment;
- mTargetRequestCode = requestCode;
- }
-
- /**
- * Return the target fragment set by {@link #setTargetFragment}.
- */
- final public Fragment getTargetFragment() {
- return mTarget;
- }
-
- /**
- * Return the target request code set by {@link #setTargetFragment}.
- */
- final public int getTargetRequestCode() {
- return mTargetRequestCode;
- }
-
- /**
- * Return the Activity this fragment is currently associated with.
- *
- * @see #getSupportActivity()
- */
- final public Activity getActivity() {
- return (mActivity != null) ? mActivity.asActivity() : null;
- }
-
- /**
- * Return the SupportActivity interface for the activity in which this
- * fragment is currently associated.
- *
- * @see #getActivity()
- */
- final public SupportActivity getSupportActivity() {
- return mActivity;
- }
-
- /**
- * Return getActivity().getResources()
.
- */
- final public Resources getResources() {
- if (mActivity == null) {
- throw new IllegalStateException("Fragment " + this + " not attached to Activity");
- }
- return mActivity.getResources();
- }
-
- /**
- * Return a localized, styled CharSequence from the application's package's
- * default string table.
- *
- * @param resId Resource id for the CharSequence text
- */
- public final CharSequence getText(int resId) {
- return getResources().getText(resId);
- }
-
- /**
- * Return a localized string from the application's package's
- * default string table.
- *
- * @param resId Resource id for the string
- */
- public final String getString(int resId) {
- return getResources().getString(resId);
- }
-
- /**
- * Return a localized formatted string from the application's package's
- * default string table, substituting the format arguments as defined in
- * {@link java.util.Formatter} and {@link java.lang.String#format}.
- *
- * @param resId Resource id for the format string
- * @param formatArgs The format arguments that will be used for substitution.
- */
-
- public final String getString(int resId, Object... formatArgs) {
- return getResources().getString(resId, formatArgs);
- }
-
- /**
- * Return the FragmentManager for interacting with fragments associated
- * with this fragment's activity. Note that this will be non-null slightly
- * before {@link #getActivity()}, during the time from when the fragment is
- * placed in a {@link FragmentTransaction} until it is committed and
- * attached to its activity.
- */
- final public FragmentManager getFragmentManager() {
- return mFragmentManager;
- }
-
- /**
- * A clone of {@link #getFragmentManager()} to maintain naming conventions
- * throughout the compatibility library.
- */
- final public FragmentManager getSupportFragmentManager() {
- return mFragmentManager;
- }
-
- /**
- * Return true if the fragment is currently added to its activity.
- */
- final public boolean isAdded() {
- return mActivity != null && mAdded;
- }
-
- /**
- * Return true if the fragment has been explicitly detached from the UI.
- * That is, {@link FragmentTransaction#detach(Fragment)
- * FragmentTransaction.detach(Fragment)} has been used on it.
- */
- final public boolean isDetached() {
- return mDetached;
- }
-
- /**
- * Return true if this fragment is currently being removed from its
- * activity. This is not whether its activity is finishing, but
- * rather whether it is in the process of being removed from its activity.
- */
- final public boolean isRemoving() {
- return mRemoving;
- }
-
- /**
- * Return true if the layout is included as part of an activity view
- * hierarchy via the <fragment> tag. This will always be true when
- * fragments are created through the <fragment> tag, except
- * in the case where an old fragment is restored from a previous state and
- * it does not appear in the layout of the current state.
- */
- final public boolean isInLayout() {
- return mInLayout;
- }
-
- /**
- * Return true if the fragment is in the resumed state. This is true
- * for the duration of {@link #onResume()} and {@link #onPause()} as well.
- */
- final public boolean isResumed() {
- return mResumed;
- }
-
- /**
- * Return true if the fragment is currently visible to the user. This means
- * it: (1) has been added, (2) has its view attached to the window, and
- * (3) is not hidden.
- */
- final public boolean isVisible() {
- return isAdded() && !isHidden() && mView != null
- && mView.getWindowToken() != null && mView.getVisibility() == View.VISIBLE;
- }
-
- /**
- * Return true if the fragment has been hidden. By default fragments
- * are shown. You can find out about changes to this state with
- * {@link #onHiddenChanged}. Note that the hidden state is orthogonal
- * to other states -- that is, to be visible to the user, a fragment
- * must be both started and not hidden.
- */
- final public boolean isHidden() {
- return mHidden;
- }
-
- /**
- * Called when the hidden state (as returned by {@link #isHidden()} of
- * the fragment has changed. Fragments start out not hidden; this will
- * be called whenever the fragment changes state from that.
- * @param hidden True if the fragment is now hidden, false if it is not
- * visible.
- */
- public void onHiddenChanged(boolean hidden) {
- }
-
- /**
- * Control whether a fragment instance is retained across Activity
- * re-creation (such as from a configuration change). This can only
- * be used with fragments not in the back stack. If set, the fragment
- * lifecycle will be slightly different when an activity is recreated:
- *
An app may set this to false to indicate that the fragment's UI is
- * scrolled out of visibility or is otherwise not directly visible to the user.
- * This may be used by the system to prioritize operations such as fragment lifecycle updates
- * or loader ordering behavior.
- *
- * @param isVisibleToUser true if this fragment's UI is currently visible to the user (default),
- * false if it is not.
- */
- public void setUserVisibleHint(boolean isVisibleToUser) {
- if (!mUserVisibleHint && isVisibleToUser && mState < STARTED) {
- mFragmentManager.performPendingDeferredStart(this);
- }
- mUserVisibleHint = isVisibleToUser;
- mDeferStart = !isVisibleToUser;
- }
-
- /**
- * @return The current value of the user-visible hint on this fragment.
- * @see #setUserVisibleHint(boolean)
- */
- public boolean getUserVisibleHint() {
- return mUserVisibleHint;
- }
-
- /**
- * Return the LoaderManager for this fragment, creating it if needed.
- */
- public LoaderManager getLoaderManager() {
- if (mLoaderManager != null) {
- return mLoaderManager;
- }
- if (mActivity == null) {
- throw new IllegalStateException("Fragment " + this + " not attached to Activity");
- }
- mCheckedForLoaderManager = true;
- mLoaderManager = mActivity.getInternalCallbacks().getLoaderManager(mIndex, mLoadersStarted, true);
- return mLoaderManager;
- }
-
- /**
- * Call {@link Activity#startActivity(Intent)} on the fragment's
- * containing Activity.
- */
- public void startActivity(Intent intent) {
- if (mActivity == null) {
- throw new IllegalStateException("Fragment " + this + " not attached to Activity");
- }
- mActivity.startActivityFromFragment(this, intent, -1);
- }
-
- /**
- * Call {@link Activity#startActivityForResult(Intent, int)} on the fragment's
- * containing Activity.
- */
- public void startActivityForResult(Intent intent, int requestCode) {
- if (mActivity == null) {
- throw new IllegalStateException("Fragment " + this + " not attached to Activity");
- }
- mActivity.startActivityFromFragment(this, intent, requestCode);
- }
-
- /**
- * Receive the result from a previous call to
- * {@link #startActivityForResult(Intent, int)}. This follows the
- * related Activity API as described there in
- * {@link Activity#onActivityResult(int, int, Intent)}.
- *
- * @param requestCode The integer request code originally supplied to
- * startActivityForResult(), allowing you to identify who this
- * result came from.
- * @param resultCode The integer result code returned by the child activity
- * through its setResult().
- * @param data An Intent, which can return result data to the caller
- * (various data can be attached to Intent "extras").
- */
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- }
-
- /**
- * @hide Hack so that DialogFragment can make its Dialog before creating
- * its views, and the view construction can use the dialog's context for
- * inflation. Maybe this should become a public API. Note sure.
- */
- public LayoutInflater getLayoutInflater(Bundle savedInstanceState) {
- return mActivity.getLayoutInflater();
- }
-
- /**
- * Called when a fragment is being created as part of a view layout
- * inflation, typically from setting the content view of an activity. This
- * may be called immediately after the fragment is created from a
- * tag in a layout file. Note this is before the fragment's
- * {@link #onAttach(Activity)} has been called; all you should do here is
- * parse the attributes and save them away.
- *
- * This is called every time the fragment is inflated, even if it is
- * being inflated into a new instance with saved state. It typically makes
- * sense to re-parse the parameters each time, to allow them to change with
- * different configurations.
- *
- * Here is a typical implementation of a fragment that can take parameters
- * both through attributes supplied here as well from {@link #getArguments()}:
- *
- * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentArguments.java
- * fragment}
- *
- * Note that parsing the XML attributes uses a "styleable" resource. The
- * declaration for the styleable used here is:
- *
- * {@sample development/samples/ApiDemos/res/values/attrs.xml fragment_arguments}
- *
- * The fragment can then be declared within its activity's content layout
- * through a tag like this:
- *
- * {@sample development/samples/ApiDemos/res/layout/fragment_arguments.xml from_attributes}
- *
- * This fragment can also be created dynamically from arguments given
- * at runtime in the arguments Bundle; here is an example of doing so at
- * creation of the containing activity:
- *
- * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentArguments.java
- * create}
- *
- * @param activity The Activity that is inflating this fragment.
- * @param attrs The attributes at the tag where the fragment is
- * being created.
- * @param savedInstanceState If the fragment is being re-created from
- * a previous saved state, this is the state.
- */
- public void onInflate(SupportActivity activity, AttributeSet attrs, Bundle savedInstanceState) {
- mCalled = true;
- }
-
- /**
- * Called when a fragment is first attached to its activity.
- * {@link #onCreate(Bundle)} will be called after this.
- */
- public void onAttach(SupportActivity activity) {
- mCalled = true;
- }
-
- /**
- * Called when a fragment loads an animation.
- */
- public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
- return null;
- }
-
- /**
- * Called to do initial creation of a fragment. This is called after
- * {@link #onAttach(Activity)} and before
- * {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}.
- *
- * Note that this can be called while the fragment's activity is
- * still in the process of being created. As such, you can not rely
- * on things like the activity's content view hierarchy being initialized
- * at this point. If you want to do work once the activity itself is
- * created, see {@link #onActivityCreated(Bundle)}.
- *
- * @param savedInstanceState If the fragment is being re-created from
- * a previous saved state, this is the state.
- */
- public void onCreate(Bundle savedInstanceState) {
- mCalled = true;
- }
-
- /**
- * Called to have the fragment instantiate its user interface view.
- * This is optional, and non-graphical fragments can return null (which
- * is the default implementation). This will be called between
- * {@link #onCreate(Bundle)} and {@link #onActivityCreated(Bundle)}.
- *
- *
If you return a View from here, you will later be called in
- * {@link #onDestroyView} when the view is being released.
- *
- * @param inflater The LayoutInflater object that can be used to inflate
- * any views in the fragment,
- * @param container If non-null, this is the parent view that the fragment's
- * UI should be attached to. The fragment should not add the view itself,
- * but this can be used to generate the LayoutParams of the view.
- * @param savedInstanceState If non-null, this fragment is being re-constructed
- * from a previous saved state as given here.
- *
- * @return Return the View for the fragment's UI, or null.
- */
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- return null;
- }
-
- /**
- * Called immediately after {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}
- * has returned, but before any saved state has been restored in to the view.
- * This gives subclasses a chance to initialize themselves once
- * they know their view hierarchy has been completely created. The fragment's
- * view hierarchy is not however attached to its parent at this point.
- * @param view The View returned by {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}.
- * @param savedInstanceState If non-null, this fragment is being re-constructed
- * from a previous saved state as given here.
- */
- public void onViewCreated(View view, Bundle savedInstanceState) {
- }
-
- /**
- * Get the root view for the fragment's layout (the one returned by {@link #onCreateView}),
- * if provided.
- *
- * @return The fragment's root view, or null if it has no layout.
- */
- public View getView() {
- return mView;
- }
-
- /**
- * Called when the fragment's activity has been created and this
- * fragment's view hierarchy instantiated. It can be used to do final
- * initialization once these pieces are in place, such as retrieving
- * views or restoring state. It is also useful for fragments that use
- * {@link #setRetainInstance(boolean)} to retain their instance,
- * as this callback tells the fragment when it is fully associated with
- * the new activity instance. This is called after {@link #onCreateView}
- * and before {@link #onStart()}.
- *
- * @param savedInstanceState If the fragment is being re-created from
- * a previous saved state, this is the state.
- */
- public void onActivityCreated(Bundle savedInstanceState) {
- mCalled = true;
- }
-
- /**
- * Called when the Fragment is visible to the user. This is generally
- * tied to {@link Activity#onStart() Activity.onStart} of the containing
- * Activity's lifecycle.
- */
- public void onStart() {
- mCalled = true;
-
- if (!mLoadersStarted) {
- mLoadersStarted = true;
- if (!mCheckedForLoaderManager) {
- mCheckedForLoaderManager = true;
- mLoaderManager = mActivity.getInternalCallbacks().getLoaderManager(mIndex, mLoadersStarted, false);
- }
- if (mLoaderManager != null) {
- mLoaderManager.doStart();
- }
- }
- }
-
- /**
- * Called when the fragment is visible to the user and actively running.
- * This is generally
- * tied to {@link Activity#onResume() Activity.onResume} of the containing
- * Activity's lifecycle.
- */
- public void onResume() {
- mCalled = true;
- }
-
- /**
- * Called to ask the fragment to save its current dynamic state, so it
- * can later be reconstructed in a new instance of its process is
- * restarted. If a new instance of the fragment later needs to be
- * created, the data you place in the Bundle here will be available
- * in the Bundle given to {@link #onCreate(Bundle)},
- * {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}, and
- * {@link #onActivityCreated(Bundle)}.
- *
- *
This corresponds to {@link Activity#onSaveInstanceState(Bundle)
- * Activity.onSaveInstanceState(Bundle)} and most of the discussion there
- * applies here as well. Note however: this method may be called
- * at any time before {@link #onDestroy()}. There are many situations
- * where a fragment may be mostly torn down (such as when placed on the
- * back stack with no UI showing), but its state will not be saved until
- * its owning activity actually needs to save its state.
- *
- * @param outState Bundle in which to place your saved state.
- */
- public void onSaveInstanceState(Bundle outState) {
- }
-
- public void onConfigurationChanged(Configuration newConfig) {
- mCalled = true;
- }
-
- /**
- * Called when the Fragment is no longer resumed. This is generally
- * tied to {@link Activity#onPause() Activity.onPause} of the containing
- * Activity's lifecycle.
- */
- public void onPause() {
- mCalled = true;
- }
-
- /**
- * Called when the Fragment is no longer started. This is generally
- * tied to {@link Activity#onStop() Activity.onStop} of the containing
- * Activity's lifecycle.
- */
- public void onStop() {
- mCalled = true;
- }
-
- public void onLowMemory() {
- mCalled = true;
- }
-
- /**
- * Called when the view previously created by {@link #onCreateView} has
- * been detached from the fragment. The next time the fragment needs
- * to be displayed, a new view will be created. This is called
- * after {@link #onStop()} and before {@link #onDestroy()}. It is called
- * regardless of whether {@link #onCreateView} returned a
- * non-null view. Internally it is called after the view's state has
- * been saved but before it has been removed from its parent.
- */
- public void onDestroyView() {
- mCalled = true;
- }
-
- /**
- * Called when the fragment is no longer in use. This is called
- * after {@link #onStop()} and before {@link #onDetach()}.
- */
- public void onDestroy() {
- mCalled = true;
- //Log.v("foo", "onDestroy: mCheckedForLoaderManager=" + mCheckedForLoaderManager
- // + " mLoaderManager=" + mLoaderManager);
- if (!mCheckedForLoaderManager) {
- mCheckedForLoaderManager = true;
- mLoaderManager = mActivity.getInternalCallbacks().getLoaderManager(mIndex, mLoadersStarted, false);
- }
- if (mLoaderManager != null) {
- mLoaderManager.doDestroy();
- }
- }
-
- /**
- * Called by the fragment manager once this fragment has been removed,
- * so that we don't have any left-over state if the application decides
- * to re-use the instance. This only clears state that the framework
- * internally manages, not things the application sets.
- */
- void initState() {
- mIndex = -1;
- mWho = null;
- mAdded = false;
- mRemoving = false;
- mResumed = false;
- mFromLayout = false;
- mInLayout = false;
- mRestored = false;
- mBackStackNesting = 0;
- mFragmentManager = null;
- mActivity = null;
- mFragmentId = 0;
- mContainerId = 0;
- mTag = null;
- mHidden = false;
- mDetached = false;
- mRetaining = false;
- mLoaderManager = null;
- mLoadersStarted = false;
- mCheckedForLoaderManager = false;
- }
-
- /**
- * Called when the fragment is no longer attached to its activity. This
- * is called after {@link #onDestroy()}.
- */
- public void onDetach() {
- mCalled = true;
- }
-
- /**
- * Initialize the contents of the Activity's standard options menu. You
- * should place your menu items in to menu. For this method
- * to be called, you must have first called {@link #setHasOptionsMenu}. See
- * {@link Activity#onCreateOptionsMenu(Menu) Activity.onCreateOptionsMenu}
- * for more information.
- *
- * @param menu The options menu in which you place your items.
- *
- * @see #setHasOptionsMenu
- * @see #onPrepareOptionsMenu
- * @see #onOptionsItemSelected
- */
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- }
-
- /**
- * Prepare the Screen's standard options menu to be displayed. This is
- * called right before the menu is shown, every time it is shown. You can
- * use this method to efficiently enable/disable items or otherwise
- * dynamically modify the contents. See
- * {@link Activity#onPrepareOptionsMenu(Menu) Activity.onPrepareOptionsMenu}
- * for more information.
- *
- * @param menu The options menu as last shown or first initialized by
- * onCreateOptionsMenu().
- *
- * @see #setHasOptionsMenu
- * @see #onCreateOptionsMenu
- */
- public void onPrepareOptionsMenu(Menu menu) {
- }
-
- /**
- * Called when this fragment's option menu items are no longer being
- * included in the overall options menu. Receiving this call means that
- * the menu needed to be rebuilt, but this fragment's items were not
- * included in the newly built menu (its {@link #onCreateOptionsMenu(Menu, MenuInflater)}
- * was not called).
- */
- public void onDestroyOptionsMenu() {
- }
-
- /**
- * This hook is called whenever an item in your options menu is selected.
- * The default implementation simply returns false to have the normal
- * processing happen (calling the item's Runnable or sending a message to
- * its Handler as appropriate). You can use this method for any items
- * for which you would like to do processing without those other
- * facilities.
- *
- *
Derived classes should call through to the base class for it to
- * perform the default menu handling.
- *
- * @param item The menu item that was selected.
- *
- * @return boolean Return false to allow normal menu processing to
- * proceed, true to consume it here.
- *
- * @see #onCreateOptionsMenu
- */
- public boolean onOptionsItemSelected(MenuItem item) {
- return false;
- }
-
- /**
- * This hook is called whenever the options menu is being closed (either by the user canceling
- * the menu with the back/menu button, or when an item is selected).
- *
- * @param menu The options menu as last shown or first initialized by
- * onCreateOptionsMenu().
- */
- public void onOptionsMenuClosed(Menu menu) {
- }
-
- /**
- * Called when a context menu for the {@code view} is about to be shown.
- * Unlike {@link #onCreateOptionsMenu}, this will be called every
- * time the context menu is about to be shown and should be populated for
- * the view (or item inside the view for {@link AdapterView} subclasses,
- * this can be found in the {@code menuInfo})).
- *
- * Use {@link #onContextItemSelected(android.view.MenuItem)} to know when an
- * item has been selected.
- *
- * The default implementation calls up to
- * {@link Activity#onCreateContextMenu Activity.onCreateContextMenu}, though
- * you can not call this implementation if you don't want that behavior.
- *
- * It is not safe to hold onto the context menu after this method returns.
- * {@inheritDoc}
- */
- public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
- getActivity().onCreateContextMenu(menu, v, menuInfo);
- }
-
- /**
- * Registers a context menu to be shown for the given view (multiple views
- * can show the context menu). This method will set the
- * {@link OnCreateContextMenuListener} on the view to this fragment, so
- * {@link #onCreateContextMenu(ContextMenu, View, ContextMenuInfo)} will be
- * called when it is time to show the context menu.
- *
- * @see #unregisterForContextMenu(View)
- * @param view The view that should show a context menu.
- */
- public void registerForContextMenu(View view) {
- view.setOnCreateContextMenuListener(this);
- }
-
- /**
- * Prevents a context menu to be shown for the given view. This method will
- * remove the {@link OnCreateContextMenuListener} on the view.
- *
- * @see #registerForContextMenu(View)
- * @param view The view that should stop showing a context menu.
- */
- public void unregisterForContextMenu(View view) {
- view.setOnCreateContextMenuListener(null);
- }
-
- /**
- * This hook is called whenever an item in a context menu is selected. The
- * default implementation simply returns false to have the normal processing
- * happen (calling the item's Runnable or sending a message to its Handler
- * as appropriate). You can use this method for any items for which you
- * would like to do processing without those other facilities.
- *
- * Use {@link MenuItem#getMenuInfo()} to get extra information set by the
- * View that added this menu item.
- *
- * Derived classes should call through to the base class for it to perform
- * the default menu handling.
- *
- * @param item The context menu item that was selected.
- * @return boolean Return false to allow normal context menu processing to
- * proceed, true to consume it here.
- */
- public boolean onContextItemSelected(MenuItem item) {
- return false;
- }
-
- /**
- * Print the Fragments's state into the given stream.
- *
- * @param prefix Text to print at the front of each line.
- * @param fd The raw file descriptor that the dump is being sent to.
- * @param writer The PrintWriter to which you should dump your state. This will be
- * closed for you after you return.
- * @param args additional arguments to the dump request.
- */
- public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
- writer.print(prefix); writer.print("mFragmentId=#");
- writer.print(Integer.toHexString(mFragmentId));
- writer.print(" mContainerId#=");
- writer.print(Integer.toHexString(mContainerId));
- writer.print(" mTag="); writer.println(mTag);
- writer.print(prefix); writer.print("mState="); writer.print(mState);
- writer.print(" mIndex="); writer.print(mIndex);
- writer.print(" mWho="); writer.print(mWho);
- writer.print(" mBackStackNesting="); writer.println(mBackStackNesting);
- writer.print(prefix); writer.print("mAdded="); writer.print(mAdded);
- writer.print(" mRemoving="); writer.print(mRemoving);
- writer.print(" mResumed="); writer.print(mResumed);
- writer.print(" mFromLayout="); writer.print(mFromLayout);
- writer.print(" mInLayout="); writer.println(mInLayout);
- writer.print(prefix); writer.print("mHidden="); writer.print(mHidden);
- writer.print(" mDetached="); writer.print(mDetached);
- writer.print(" mMenuVisible="); writer.print(mMenuVisible);
- writer.print(" mHasMenu="); writer.println(mHasMenu);
- writer.print(prefix); writer.print("mRetainInstance="); writer.print(mRetainInstance);
- writer.print(" mRetaining="); writer.print(mRetaining);
- writer.print(" mUserVisibleHint="); writer.println(mUserVisibleHint);
- if (mFragmentManager != null) {
- writer.print(prefix); writer.print("mFragmentManager=");
- writer.println(mFragmentManager);
- }
- if (mActivity != null) {
- writer.print(prefix); writer.print("mActivity=");
- writer.println(mActivity);
- }
- if (mArguments != null) {
- writer.print(prefix); writer.print("mArguments="); writer.println(mArguments);
- }
- if (mSavedFragmentState != null) {
- writer.print(prefix); writer.print("mSavedFragmentState=");
- writer.println(mSavedFragmentState);
- }
- if (mSavedViewState != null) {
- writer.print(prefix); writer.print("mSavedViewState=");
- writer.println(mSavedViewState);
- }
- if (mTarget != null) {
- writer.print(prefix); writer.print("mTarget="); writer.print(mTarget);
- writer.print(" mTargetRequestCode=");
- writer.println(mTargetRequestCode);
- }
- if (mNextAnim != 0) {
- writer.print(prefix); writer.print("mNextAnim="); writer.println(mNextAnim);
- }
- if (mContainer != null) {
- writer.print(prefix); writer.print("mContainer="); writer.println(mContainer);
- }
- if (mView != null) {
- writer.print(prefix); writer.print("mView="); writer.println(mView);
- }
- if (mInnerView != null) {
- writer.print(prefix); writer.print("mInnerView="); writer.println(mView);
- }
- if (mAnimatingAway != null) {
- writer.print(prefix); writer.print("mAnimatingAway="); writer.println(mAnimatingAway);
- writer.print(prefix); writer.print("mStateAfterAnimating=");
- writer.println(mStateAfterAnimating);
- }
- if (mLoaderManager != null) {
- writer.print(prefix); writer.println("Loader Manager:");
- mLoaderManager.dump(prefix + " ", fd, writer, args);
- }
- }
-
- void performStart() {
- onStart();
- if (mLoaderManager != null) {
- mLoaderManager.doReportStart();
- }
- }
-
- void performStop() {
- onStop();
- }
-
- void performReallyStop() {
- if (mLoadersStarted) {
- mLoadersStarted = false;
- if (!mCheckedForLoaderManager) {
- mCheckedForLoaderManager = true;
- mLoaderManager = mActivity.getInternalCallbacks().getLoaderManager(mIndex, mLoadersStarted, false);
- }
- if (mLoaderManager != null) {
- if (!mActivity.getInternalCallbacks().getRetaining()) {
- mLoaderManager.doStop();
- } else {
- mLoaderManager.doRetain();
- }
- }
- }
- }
-
- void performDestroyView() {
- onDestroyView();
- if (mLoaderManager != null) {
- mLoaderManager.doReportNextStart();
- }
- }
-}
diff --git a/actionbarsherlock/library/src/android/support/v4/app/FragmentActivity.java b/actionbarsherlock/library/src/android/support/v4/app/FragmentActivity.java
deleted file mode 100644
index 16f9916cd..000000000
--- a/actionbarsherlock/library/src/android/support/v4/app/FragmentActivity.java
+++ /dev/null
@@ -1,1361 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- * Copyright (C) 2011 Jake Wharton
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v4.app;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.content.res.TypedArray;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Parcelable;
-import android.support.v4.view.ActionMode;
-import android.support.v4.view.Menu;
-import android.support.v4.view.MenuItem;
-import android.support.v4.view.Window;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-import com.actionbarsherlock.R;
-import com.actionbarsherlock.internal.app.ActionBarImpl;
-import com.actionbarsherlock.internal.app.ActionBarWrapper;
-import com.actionbarsherlock.internal.view.menu.MenuBuilder;
-import com.actionbarsherlock.internal.view.menu.MenuInflaterImpl;
-import com.actionbarsherlock.internal.view.menu.MenuInflaterWrapper;
-import com.actionbarsherlock.internal.view.menu.MenuItemImpl;
-import com.actionbarsherlock.internal.view.menu.MenuItemWrapper;
-import com.actionbarsherlock.internal.view.menu.MenuPresenter;
-import com.actionbarsherlock.internal.view.menu.MenuWrapper;
-import com.actionbarsherlock.internal.widget.ActionBarView;
-
-/**
- * Base class for activities that want to use the support-based
- * {@link android.support.v4.app.Fragment},
- * {@link android.support.v4.content.Loader}, and
- * {@link android.support.v4.app.ActionBar} APIs.
- *
- * When using this class as opposed to new platform's built-in fragment
- * and loader support, you must use the {@link #getSupportFragmentManager()}
- * and {@link #getSupportLoaderManager()} methods respectively to access
- * those features.
- *
- *
Known limitations:
- *
- * -
When using the <fragment> tag, this implementation can not
- * use the parent view's ID as the new fragment's ID. You must explicitly
- * specify an ID (or tag) in the <fragment>.
- * -
Prior to Honeycomb (3.0), an activity's state was saved before pausing.
- * Fragments are a significant amount of new state, and dynamic enough that one
- * often wants them to change between pausing and stopping. These classes
- * throw an exception if you try to change the fragment state after it has been
- * saved, to avoid accidental loss of UI state. However this is too restrictive
- * prior to Honeycomb, where the state is saved before pausing. To address this,
- * when running on platforms prior to Honeycomb an exception will not be thrown
- * if you change fragments between the state save and the activity being stopped.
- * This means that in some cases if the activity is restored from its last saved
- * state, this may be a snapshot slightly before what the user last saw.
- *
- */
-public class FragmentActivity extends Activity implements SupportActivity {
- private static final String TAG = "FragmentActivity";
- private static final boolean DEBUG = false;
-
- private static final String FRAGMENTS_TAG = "android:support:fragments";
-
- static final boolean IS_HONEYCOMB = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB;
-
- static final int MSG_REALLY_STOPPED = 1;
- static final int MSG_RESUME_PENDING = 2;
-
- final SupportActivity.InternalCallbacks mInternalCallbacks = new SupportActivity.InternalCallbacks() {
- @Override
- void invalidateSupportFragmentIndex(int index) {
- FragmentActivity.this.invalidateSupportFragmentIndex(index);
- }
-
- @Override
- LoaderManagerImpl getLoaderManager(int index, boolean started, boolean create) {
- return FragmentActivity.this.getLoaderManager(index, started, create);
- }
-
- @Override
- Handler getHandler() {
- return mHandler;
- }
-
- @Override
- FragmentManagerImpl getFragments() {
- return mFragments;
- }
-
- @Override
- boolean getRetaining() {
- return mRetaining;
- }
- };
-
- final Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_REALLY_STOPPED:
- if (mStopped) {
- doReallyStop(false);
- }
- break;
- case MSG_RESUME_PENDING:
- mFragments.dispatchResume();
- mFragments.execPendingActions();
- break;
- default:
- super.handleMessage(msg);
- }
- }
- };
- final FragmentManagerImpl mFragments = new FragmentManagerImpl();
-
- ViewGroup mDecor;
- ViewGroup mContentParent;
- ActionBar mActionBar;
- ActionBarView mActionBarView;
- long mWindowFlags = 0;
-
- android.view.MenuInflater mMenuInflater;
-
- MenuBuilder mSupportMenu;
- final MenuBuilder.Callback mSupportMenuCallback = new MenuBuilder.Callback() {
- @Override
- public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
- return FragmentActivity.this.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, item);
- }
-
- @Override
- public void onMenuModeChange(MenuBuilder menu) {
- // No-op
- }
- };
- private final MenuPresenter.Callback mMenuPresenterCallback = new MenuPresenter.Callback() {
- @Override
- public boolean onOpenSubMenu(MenuBuilder subMenu) {
- return false;
- }
-
- @Override
- public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
- }
- };
-
- /** Map between native options items and sherlock items (pre-3.0 only). */
- private HashMap mNativeItemMap;
- /** Native menu item callback which proxies to our callback. */
- private final android.view.MenuItem.OnMenuItemClickListener mNativeItemListener = new android.view.MenuItem.OnMenuItemClickListener() {
- @Override
- public boolean onMenuItemClick(android.view.MenuItem item) {
- if (DEBUG) Log.d(TAG, "[mNativeItemListener.onMenuItemClick] item: " + item);
-
- final MenuItemImpl sherlockItem = mNativeItemMap.get(item);
- if (sherlockItem != null) {
- sherlockItem.invoke();
- } else {
- Log.e(TAG, "Options item \"" + item + "\" not found in mapping");
- }
-
- return true; //Do not allow continuation of native handling
- }
- };
-
- boolean mCreated;
- boolean mResumed;
- boolean mStopped;
- boolean mReallyStopped;
- boolean mRetaining;
-
- boolean mOptionsMenuInvalidated;
- boolean mOptionsMenuCreateResult;
-
- boolean mCheckedForLoaderManager;
- boolean mLoadersStarted;
- HCSparseArray mAllLoaderManagers;
- LoaderManagerImpl mLoaderManager;
-
- static final class NonConfigurationInstances {
- Object activity;
- Object custom;
- HashMap children;
- ArrayList fragments;
- HCSparseArray loaders;
- }
-
- static class FragmentTag {
- public static final int[] Fragment = {
- 0x01010003, 0x010100d0, 0x010100d1
- };
- public static final int Fragment_id = 1;
- public static final int Fragment_name = 0;
- public static final int Fragment_tag = 2;
- }
-
-
-
-
-
- @Override
- public SupportActivity.InternalCallbacks getInternalCallbacks() {
- return mInternalCallbacks;
- }
-
- @Override
- public Activity asActivity() {
- return this;
- }
-
- private void initActionBar() {
- if (DEBUG) Log.d(TAG, "[initActionBar]");
-
- // Initializing the window decor can change window feature flags.
- // Make sure that we have the correct set before performing the test below.
- if (mDecor == null) {
- installDecor();
- }
-
- if ((mActionBar != null) || !hasFeature(Window.FEATURE_ACTION_BAR) || isChild()) {
- return;
- }
-
- if (IS_HONEYCOMB) {
- mActionBar = ActionBarWrapper.createFor(this);
- } else {
- mActionBar = new ActionBarImpl(this);
- }
- }
-
- private void installDecor() {
- if (DEBUG) Log.d(TAG, "[installDecor]");
-
- if (mDecor == null) {
- if (IS_HONEYCOMB) {
- mDecor = (ViewGroup)getWindow().getDecorView();
- } else {
- mDecor = (ViewGroup)getWindow().getDecorView().findViewById(android.R.id.content);
- }
- }
- if (mContentParent == null) {
- if (IS_HONEYCOMB) {
- mContentParent = (ViewGroup)mDecor.findViewById(android.R.id.content);
- } else {
- mContentParent = generateLayout();
- mActionBarView = (ActionBarView)mDecor.findViewById(R.id.abs__action_bar);
- if (mActionBarView != null) {
- if (mActionBarView.getTitle() == null) {
- mActionBarView.setTitle(getTitle());
- }
- if (hasFeature(Window.FEATURE_INDETERMINATE_PROGRESS)) {
- mActionBarView.initIndeterminateProgress();
- }
- }
-
- // Post the panel invalidate for later; avoid application onCreateOptionsMenu
- // being called in the middle of onCreate or similar.
- mDecor.post(new Runnable() {
- @Override
- public void run() {
- //Invalidate if the panel menu hasn't been created before this.
- if (mSupportMenu == null) {
- invalidateOptionsMenu();
- }
- }
- });
- }
- }
- }
-
- private ViewGroup generateLayout() {
- if (DEBUG) Log.d(TAG, "[generateLayout]");
-
- // Apply data from current theme.
-
- TypedArray a = getTheme().obtainStyledAttributes(R.styleable.SherlockTheme);
-
- if (a.getBoolean(R.styleable.SherlockTheme_windowNoTitle, false)) {
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- } else if (a.getBoolean(R.styleable.SherlockTheme_windowActionBar, false)) {
- // Don't allow an action bar if there is no title.
- requestWindowFeature(Window.FEATURE_ACTION_BAR);
- }
-
- if (a.getBoolean(R.styleable.SherlockTheme_windowActionBarOverlay, false)) {
- requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
- }
-
- if (a.getBoolean(R.styleable.SherlockTheme_windowActionModeOverlay, false)) {
- requestWindowFeature(Window.FEATURE_ACTION_MODE_OVERLAY);
- }
-
- a.recycle();
-
- int layoutResource;
- if (hasFeature(Window.FEATURE_ACTION_BAR)) {
- if (hasFeature(Window.FEATURE_ACTION_BAR_OVERLAY)) {
- layoutResource = R.layout.abs__screen_action_bar_overlay;
- } else {
- layoutResource = R.layout.abs__screen_action_bar;
- }
- //} else if (hasFeature(Window.FEATURE_ACTION_MODE_OVERLAY)) {
- // layoutResource = R.layout.abs__screen_simple_overlay_action_mode;
- } else {
- layoutResource = R.layout.abs__screen_simple;
- }
-
- View in = getLayoutInflater().inflate(layoutResource, null);
- mDecor.addView(in, new ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
-
- ViewGroup contentParent = (ViewGroup)mDecor.findViewById(R.id.abs__content);
- if (contentParent == null) {
- throw new RuntimeException("Couldn't find content container view");
- }
-
- //Make our new child the true content view (for fragments). VERY VOLATILE!
- mDecor.setId(View.NO_ID);
- contentParent.setId(android.R.id.content);
-
- return contentParent;
- }
-
- private boolean hasFeature(long featureId) {
- if (IS_HONEYCOMB) {
- return getWindow().hasFeature((int)featureId);
- }
- return (mWindowFlags & (1 << featureId)) != 0;
- }
-
- // ------------------------------------------------------------------------
- // HOOKS INTO ACTIVITY
- // ------------------------------------------------------------------------
-
- /**
- * Enable extended window features.
- *
- * @param featureId The desired feature as defined in
- * {@link android.support.v4.view.Window}.
- * @return Returns {@code true} if the requested feature is supported and
- * now enabled.
- */
- @Override
- public boolean requestWindowFeature(long featureId) {
- if (!IS_HONEYCOMB) {
- switch ((int)featureId) {
- case (int)Window.FEATURE_ACTION_BAR:
- case (int)Window.FEATURE_ACTION_BAR_OVERLAY:
- case (int)Window.FEATURE_ACTION_MODE_OVERLAY:
- case (int)Window.FEATURE_INDETERMINATE_PROGRESS:
- mWindowFlags |= (1 << featureId);
- return true;
- }
- }
- return super.requestWindowFeature((int)featureId);
- }
-
- @Override
- public android.view.MenuInflater getMenuInflater() {
- if (DEBUG) Log.d(TAG, "[getMenuInflater]");
-
- if (mMenuInflater == null) {
- initActionBar();
- }
- if (IS_HONEYCOMB) {
- if (DEBUG) Log.d(TAG, "getMenuInflater(): Wrapping native inflater.");
-
- //Wrap the native inflater so it can unwrap the native menu first
- mMenuInflater = new MenuInflaterWrapper(this, super.getMenuInflater());
- } else {
- if (DEBUG) Log.d(TAG, "getMenuInflater(): Returning support inflater.");
-
- //Use our custom menu inflater
- mMenuInflater = new MenuInflaterImpl(this, super.getMenuInflater());
- }
-
- return mMenuInflater;
- }
-
- @Override
- public void setContentView(int layoutResId) {
- if (DEBUG) Log.d(TAG, "[setContentView] layoutResId: " + layoutResId);
-
- if (mContentParent == null) {
- installDecor();
- } else {
- mContentParent.removeAllViews();
- }
- getLayoutInflater().inflate(layoutResId, mContentParent);
-
- android.view.Window.Callback callback = getWindow().getCallback();
- if (callback != null) {
- callback.onContentChanged();
- }
- initActionBar();
- }
-
- @Override
- public void setContentView(View view, LayoutParams params) {
- if (DEBUG) Log.d(TAG, "[setContentView] view: " + view + ", params: " + params);
-
- if (mContentParent == null) {
- installDecor();
- } else {
- mContentParent.removeAllViews();
- }
- mContentParent.addView(view, params);
-
- android.view.Window.Callback callback = getWindow().getCallback();
- if (callback != null) {
- callback.onContentChanged();
- }
-
- initActionBar();
- }
-
- @Override
- public void setContentView(View view) {
- if (DEBUG) Log.d(TAG, "[setContentView] view: " + view);
-
- setContentView(view, new ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
- }
-
- @Override
- public void addContentView(View view, ViewGroup.LayoutParams params) {
- if (DEBUG) Log.d(TAG, "[addContentView] view: " + view + ", params: " + params);
-
- if (mContentParent == null) {
- installDecor();
- }
- mContentParent.addView(view, params);
-
- initActionBar();
- }
-
- @Override
- public void setTitle(CharSequence title) {
- if (IS_HONEYCOMB || (mActionBar == null)) {
- super.setTitle(title);
- } else {
- getSupportActionBar().setTitle(title);
- }
- }
-
- @Override
- public void setTitle(int titleId) {
- if (IS_HONEYCOMB || (mActionBar == null)) {
- super.setTitle(titleId);
- } else {
- getSupportActionBar().setTitle(titleId);
- }
- }
-
- /**
- * Dispatch incoming result to the correct fragment.
- */
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- int index = requestCode>>16;
- if (index != 0) {
- index--;
- if (mFragments.mActive == null || index < 0 || index >= mFragments.mActive.size()) {
- Log.w(TAG, "Activity result fragment index out of range: 0x"
- + Integer.toHexString(requestCode));
- return;
- }
- Fragment frag = mFragments.mActive.get(index);
- if (frag == null) {
- Log.w(TAG, "Activity result no fragment exists for index: 0x"
- + Integer.toHexString(requestCode));
- } else {
- frag.onActivityResult(requestCode&0xffff, resultCode, data);
- }
- return;
- }
-
- super.onActivityResult(requestCode, resultCode, data);
- }
-
- /**
- * Take care of popping the fragment back stack or finishing the activity
- * as appropriate.
- */
- @Override
- public void onBackPressed() {
- if (!mFragments.popBackStackImmediate()) {
- finish();
- }
- }
-
- /**
- * Dispatch configuration change to all fragments.
- */
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- mFragments.dispatchConfigurationChanged(newConfig);
- }
-
- /**
- * Perform initialization of all fragments and loaders.
- */
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- mFragments.attachActivity(this);
- // Old versions of the platform didn't do this!
- if (getLayoutInflater().getFactory() == null) {
- getLayoutInflater().setFactory(this);
- }
-
- super.onCreate(savedInstanceState);
-
- NonConfigurationInstances nc = (NonConfigurationInstances)
- getLastNonConfigurationInstance();
- if (nc != null) {
- mAllLoaderManagers = nc.loaders;
- }
- if (savedInstanceState != null) {
- Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
- mFragments.restoreAllState(p, nc != null ? nc.fragments : null);
- }
- mFragments.dispatchCreate();
- }
-
- /**
- * Initialize the contents of the Activity's standard options menu. You
- * should place your menu items in to menu.
- *
- * The default implementation populates the menu with standard system
- * menu items. These are placed in the {@link Menu.CATEGORY_SYSTEM} group
- * so that they will be correctly ordered with application-defined menu
- * items. Deriving classes should always call through to the base
- * implementation.
- *
- * You can safely hold on to menu (and any items created from it),
- * making modifications to it as desired, until the next time
- * {@code onCreateOptionsMenu()} is called.
- *
- * When you add items to the menu, you can implement the Activity's
- * {@link #onOptionsItemSelected(MenuItem)} method to handle them
- * there.
- *
- * @param menu The options menu in which you place your items.
- * @return You must return true for the menu to be displayed; if you return
- * false it will not be shown.
- */
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- if (DEBUG) Log.d(TAG, "onCreateOptionsMenu(Menu): Returning true");
- return true;
- }
-
- @Override
- public final boolean onCreateOptionsMenu(android.view.Menu menu) {
- // Prior to Honeycomb, the framework can't invalidate the options
- // menu, so we must always say we have one in case the app later
- // invalidates it and needs to have it shown.
- boolean result = true;
-
- if (IS_HONEYCOMB) {
- if (DEBUG) Log.d(TAG, "onCreateOptionsMenu(android.view.Menu): Calling support method with wrapped native menu.");
- MenuWrapper wrapped = new MenuWrapper(menu);
- result = onCreateOptionsMenu(wrapped);
- result |= mFragments.dispatchCreateOptionsMenu(wrapped, getMenuInflater());
- }
-
- if (DEBUG) Log.d(TAG, "onCreateOptionsMenu(android.view.Menu): Returning " + result);
- return result;
- }
-
- private boolean dispatchCreateOptionsMenu() {
- if (DEBUG) Log.d(TAG, "[dispatchCreateOptionsMenu]");
-
- boolean result = onCreateOptionsMenu(mSupportMenu);
- result |= mFragments.dispatchCreateOptionsMenu(mSupportMenu, getMenuInflater());
- return result;
- }
-
- /**
- * Add support for inflating the <fragment> tag.
- */
- @Override
- public View onCreateView(String name, Context context, AttributeSet attrs) {
- if (!"fragment".equals(name)) {
- return super.onCreateView(name, context, attrs);
- }
-
- String fname = attrs.getAttributeValue(null, "class");
- TypedArray a = context.obtainStyledAttributes(attrs, FragmentTag.Fragment);
- if (fname == null) {
- fname = a.getString(FragmentTag.Fragment_name);
- }
- int id = a.getResourceId(FragmentTag.Fragment_id, View.NO_ID);
- String tag = a.getString(FragmentTag.Fragment_tag);
- a.recycle();
-
- View parent = null; // NOTE: no way to get parent pre-Honeycomb.
- int containerId = parent != null ? parent.getId() : 0;
- if (containerId == View.NO_ID && id == View.NO_ID && tag == null) {
- throw new IllegalArgumentException(attrs.getPositionDescription()
- + ": Must specify unique android:id, android:tag, or have a parent with an id for " + fname);
- }
-
- // If we restored from a previous state, we may already have
- // instantiated this fragment from the state and should use
- // that instance instead of making a new one.
- Fragment fragment = id != View.NO_ID ? mFragments.findFragmentById(id) : null;
- if (fragment == null && tag != null) {
- fragment = mFragments.findFragmentByTag(tag);
- }
- if (fragment == null && containerId != View.NO_ID) {
- fragment = mFragments.findFragmentById(containerId);
- }
-
- if (FragmentManagerImpl.DEBUG) Log.v(TAG, "onCreateView: id=0x"
- + Integer.toHexString(id) + " fname=" + fname
- + " existing=" + fragment);
- if (fragment == null) {
- fragment = Fragment.instantiate(this, fname);
- fragment.mFromLayout = true;
- fragment.mFragmentId = id != 0 ? id : containerId;
- fragment.mContainerId = containerId;
- fragment.mTag = tag;
- fragment.mInLayout = true;
- fragment.mFragmentManager = mFragments;
- fragment.onInflate(this, attrs, fragment.mSavedFragmentState);
- mFragments.addFragment(fragment, true);
-
- } else if (fragment.mInLayout) {
- // A fragment already exists and it is not one we restored from
- // previous state.
- throw new IllegalArgumentException(attrs.getPositionDescription()
- + ": Duplicate id 0x" + Integer.toHexString(id)
- + ", tag " + tag + ", or parent id 0x" + Integer.toHexString(containerId)
- + " with another fragment for " + fname);
- } else {
- // This fragment was retained from a previous instance; get it
- // going now.
- fragment.mInLayout = true;
- // If this fragment is newly instantiated (either right now, or
- // from last saved state), then give it the attributes to
- // initialize itself.
- if (!fragment.mRetaining) {
- fragment.onInflate(this, attrs, fragment.mSavedFragmentState);
- }
- mFragments.moveToState(fragment);
- }
-
- if (fragment.mView == null) {
- throw new IllegalStateException("Fragment " + fname
- + " did not create a view.");
- }
- if (id != 0) {
- fragment.mView.setId(id);
- }
- if (fragment.mView.getTag() == null) {
- fragment.mView.setTag(tag);
- }
- return fragment.mView;
- }
-
- @Override
- public void invalidateOptionsMenu() {
- if (DEBUG) Log.d(TAG, "[invalidateOptionsMenu]");
-
- if (IS_HONEYCOMB) {
- HoneycombInvalidateOptionsMenu.invoke(this);
- return;
- }
-
- if (mSupportMenu == null) {
- mSupportMenu = new MenuBuilder(this);
- mSupportMenu.setCallback(mSupportMenuCallback);
- }
-
- mSupportMenu.stopDispatchingItemsChanged();
- mSupportMenu.clear();
-
- if (!dispatchCreateOptionsMenu()) {
- if (mActionBar != null) {
- ((ActionBarImpl)mActionBar).setMenu(null, mMenuPresenterCallback);
- }
- return;
- }
-
- if (!dispatchPrepareOptionsMenu()) {
- if (mActionBar != null) {
- ((ActionBarImpl)mActionBar).setMenu(null, mMenuPresenterCallback);
- }
- mSupportMenu.startDispatchingItemsChanged();
- return;
- }
-
- mSupportMenu.startDispatchingItemsChanged();
-
- if (mActionBar != null) {
- ((ActionBarImpl)mActionBar).setMenu(mSupportMenu, mMenuPresenterCallback);
- }
- }
-
- private static final class HoneycombInvalidateOptionsMenu {
- static void invoke(Activity activity) {
- activity.getWindow().invalidatePanelMenu(Window.FEATURE_OPTIONS_PANEL);
- }
- }
-
- /**
- * Destroy all fragments and loaders.
- */
- @Override
- protected void onDestroy() {
- super.onDestroy();
-
- doReallyStop(false);
-
- mFragments.dispatchDestroy();
- if (mLoaderManager != null) {
- mLoaderManager.doDestroy();
- }
- }
-
- /**
- * Take care of calling onBackPressed() for pre-Eclair platforms.
- */
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (android.os.Build.VERSION.SDK_INT < 5 /* ECLAIR */
- && keyCode == KeyEvent.KEYCODE_BACK
- && event.getRepeatCount() == 0) {
- // Take care of calling this method on earlier versions of
- // the platform where it doesn't exist.
- onBackPressed();
- return true;
- }
-
- return super.onKeyDown(keyCode, event);
- }
-
- /**
- * Dispatch onLowMemory() to all fragments.
- */
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mFragments.dispatchLowMemory();
- }
-
- /**
- * Dispatch context and options menu to fragments.
- */
- @Override
- public final boolean onMenuItemSelected(int featureId, android.view.MenuItem item) {
- if (super.onMenuItemSelected(featureId, item)) {
- return true;
- }
-
- switch (featureId) {
- case Window.FEATURE_OPTIONS_PANEL:
- return mFragments.dispatchOptionsItemSelected(new MenuItemWrapper(item));
-
- case Window.FEATURE_CONTEXT_MENU:
- return mFragments.dispatchContextItemSelected(new MenuItemWrapper(item));
-
- default:
- return false;
- }
- }
-
- @Override
- public boolean onMenuItemSelected(int featureId, MenuItem item) {
- if (onOptionsItemSelected(item)) {
- return true;
- }
-
- switch (featureId) {
- case Window.FEATURE_OPTIONS_PANEL:
- return mFragments.dispatchOptionsItemSelected(item);
-
- case Window.FEATURE_CONTEXT_MENU:
- return mFragments.dispatchContextItemSelected(item);
-
- default:
- return false;
- }
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- return super.onOptionsItemSelected(item);
- }
-
- @Override
- public final boolean onOptionsItemSelected(android.view.MenuItem item) {
- return onOptionsItemSelected(new MenuItemWrapper(item));
- }
-
- /**
- * Call onOptionsMenuClosed() on fragments.
- */
- @Override
- public void onPanelClosed(int featureId, android.view.Menu menu) {
- switch (featureId) {
- case Window.FEATURE_OPTIONS_PANEL:
- mFragments.dispatchOptionsMenuClosed(new MenuWrapper(menu));
-
- if (!IS_HONEYCOMB && (getSupportActionBar() != null)) {
- if (DEBUG) Log.d(TAG, "onPanelClosed(int, android.view.Menu): Dispatch menu visibility false to custom action bar.");
- ((ActionBarImpl)mActionBar).onMenuVisibilityChanged(false);
- }
- break;
- }
- super.onPanelClosed(featureId, menu);
- }
-
- /**
- * Dispatch onPause() to fragments.
- */
- @Override
- protected void onPause() {
- super.onPause();
- mResumed = false;
- if (mHandler.hasMessages(MSG_RESUME_PENDING)) {
- mHandler.removeMessages(MSG_RESUME_PENDING);
- mFragments.dispatchResume();
- }
- mFragments.dispatchPause();
- }
-
- /**
- * Dispatch onResume() to fragments.
- */
- @Override
- protected void onResume() {
- super.onResume();
- mHandler.sendEmptyMessage(MSG_RESUME_PENDING);
- mResumed = true;
- mFragments.execPendingActions();
- }
-
- /**
- * Dispatch onResume() to fragments.
- */
- @Override
- protected void onPostResume() {
- super.onPostResume();
- mHandler.removeMessages(MSG_RESUME_PENDING);
- mFragments.dispatchResume();
- mFragments.execPendingActions();
- }
-
- @Override
- public boolean onPrepareOptionsMenu(Menu menu) {
- return true;
- }
-
- @Override
- public final boolean onPrepareOptionsMenu(android.view.Menu menu) {
- if (IS_HONEYCOMB) {
- if (DEBUG) Log.d(TAG, "onPrepareOptionsMenu(android.view.Menu): Calling support method with wrapped native menu.");
- final MenuWrapper wrappedMenu = new MenuWrapper(menu);
- boolean result = onPrepareOptionsMenu(wrappedMenu);
- if (result) {
- if (DEBUG) Log.d(TAG, "onPrepareOptionsMenu(android.view.Menu): Dispatching fragment method with wrapped native menu.");
- mFragments.dispatchPrepareOptionsMenu(wrappedMenu);
- }
- return result;
- }
-
- if (!dispatchPrepareOptionsMenu()) {
- return false;
- }
-
- if (mNativeItemMap == null) {
- mNativeItemMap = new HashMap();
- } else {
- mNativeItemMap.clear();
- }
-
- if (mSupportMenu != null) {
- return mSupportMenu.bindOverflowToNative(menu, mNativeItemListener, mNativeItemMap);
- }
- return false;
- }
-
- private boolean dispatchPrepareOptionsMenu() {
- if (DEBUG) Log.d(TAG, "[dispatchPrepareOptionsMenu]");
-
- if (onPrepareOptionsMenu(mSupportMenu)) {
- mFragments.dispatchPrepareOptionsMenu(mSupportMenu);
- return true;
- }
- return false;
- }
-
- /**
- * Cause this Activity to be recreated with a new instance. This results in
- * essentially the same flow as when the Activity is created due to a
- * configuration change -- the current instance will go through its
- * lifecycle to onDestroy() and a new instance then created after it.
- */
- @Override
- public void recreate() {
- //This SUCKS! Figure out a way to call the super method and support Android 1.6
- /*
- if (IS_HONEYCOMB) {
- super.recreate();
- } else {
- */
- final Intent intent = getIntent();
- intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
-
- startActivity(intent);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
- OverridePendingTransition.invoke(this);
- }
-
- finish();
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
- OverridePendingTransition.invoke(this);
- }
- /*
- }
- */
- }
-
- private static final class OverridePendingTransition {
- static void invoke(Activity activity) {
- activity.overridePendingTransition(0, 0);
- }
- }
-
- /**
- * Retain all appropriate fragment and loader state. You can NOT
- * override this yourself! Use {@link #onRetainCustomNonConfigurationInstance()}
- * if you want to retain your own state.
- */
- @Override
- public final Object onRetainNonConfigurationInstance() {
- if (mStopped) {
- doReallyStop(true);
- }
-
- Object custom = onRetainCustomNonConfigurationInstance();
-
- ArrayList fragments = mFragments.retainNonConfig();
- boolean retainLoaders = false;
- if (mAllLoaderManagers != null) {
- // prune out any loader managers that were already stopped and so
- // have nothing useful to retain.
- for (int i=mAllLoaderManagers.size()-1; i>=0; i--) {
- LoaderManagerImpl lm = mAllLoaderManagers.valueAt(i);
- if (lm.mRetaining) {
- retainLoaders = true;
- } else {
- lm.doDestroy();
- mAllLoaderManagers.removeAt(i);
- }
- }
- }
- if (fragments == null && !retainLoaders && custom == null) {
- return null;
- }
-
- NonConfigurationInstances nci = new NonConfigurationInstances();
- nci.activity = null;
- nci.custom = custom;
- nci.children = null;
- nci.fragments = fragments;
- nci.loaders = mAllLoaderManagers;
- return nci;
- }
-
- /**
- * Save all appropriate fragment state.
- */
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- Parcelable p = mFragments.saveAllState();
- if (p != null) {
- outState.putParcelable(FRAGMENTS_TAG, p);
- }
- }
-
- /**
- * Dispatch onStart() to all fragments. Ensure any created loaders are
- * now started.
- */
- @Override
- protected void onStart() {
- super.onStart();
-
- mStopped = false;
- mReallyStopped = false;
- mHandler.removeMessages(MSG_REALLY_STOPPED);
-
- if (!mCreated) {
- mCreated = true;
- mFragments.dispatchActivityCreated();
- }
-
- mFragments.noteStateNotSaved();
- mFragments.execPendingActions();
-
- if (!mLoadersStarted) {
- mLoadersStarted = true;
- if (mLoaderManager != null) {
- mLoaderManager.doStart();
- } else if (!mCheckedForLoaderManager) {
- mLoaderManager = getLoaderManager(-1, mLoadersStarted, false);
- }
- mCheckedForLoaderManager = true;
- }
- // NOTE: HC onStart goes here.
-
- mFragments.dispatchStart();
- if (mAllLoaderManagers != null) {
- for (int i=mAllLoaderManagers.size()-1; i>=0; i--) {
- LoaderManagerImpl lm = mAllLoaderManagers.valueAt(i);
- lm.finishRetain();
- lm.doReportStart();
- }
- }
- }
-
- /**
- * Dispatch onStop() to all fragments. Ensure all loaders are stopped.
- */
- @Override
- protected void onStop() {
- super.onStop();
-
- mStopped = true;
- mHandler.sendEmptyMessage(MSG_REALLY_STOPPED);
-
- mFragments.dispatchStop();
- }
-
- /**
- * Sets the visibility of the indeterminate progress bar in the
- * title.
- *
- * In order for the progress bar to be shown, the feature must be
- * requested via {@link #requestWindowFeature(long)}.
- *
- * This method must be used instead of
- * {@link #setProgressBarIndeterminateVisibility(boolean)} for
- * ActionBarSherlock. Pass {@link Boolean.TRUE} or
- * {@link Boolean.FALSE} to ensure the appropriate one is called.
- *
- * @param visible Whether to show the progress bars in the title.
- */
- @Override
- public void setProgressBarIndeterminateVisibility(Boolean visible) {
- if (IS_HONEYCOMB || (mActionBar == null)) {
- super.setProgressBarIndeterminateVisibility(visible);
- } else {
- mActionBarView.setProgressBarIndeterminateVisibility(visible);
- }
- }
-
- // ------------------------------------------------------------------------
- // NEW METHODS
- // ------------------------------------------------------------------------
-
- /**
- * Use this instead of {@link #onRetainNonConfigurationInstance()}.
- * Retrieve later with {@link #getLastCustomNonConfigurationInstance()}.
- */
- public Object onRetainCustomNonConfigurationInstance() {
- return null;
- }
-
- /**
- * Return the value previously returned from
- * {@link #onRetainCustomNonConfigurationInstance()}.
- */
- public Object getLastCustomNonConfigurationInstance() {
- NonConfigurationInstances nc = (NonConfigurationInstances)
- getLastNonConfigurationInstance();
- return nc != null ? nc.custom : null;
- }
-
- /**
- * @deprecated Use {@link invalidateOptionsMenu}.
- */
- @Deprecated
- void supportInvalidateOptionsMenu() {
- invalidateOptionsMenu();
- }
-
- /**
- * Print the Activity's state into the given stream. This gets invoked if
- * you run "adb shell dumpsys activity ".
- *
- * @param prefix Desired prefix to prepend at each line of output.
- * @param fd The raw file descriptor that the dump is being sent to.
- * @param writer The PrintWriter to which you should dump your state. This will be
- * closed for you after you return.
- * @param args additional arguments to the dump request.
- */
- @Override
- public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
- if (IS_HONEYCOMB) {
- //This can only work if we can call the super-class impl. :/
- //ActivityCompatHoneycomb.dump(this, prefix, fd, writer, args);
- }
- writer.print(prefix); writer.print("Local FragmentActivity ");
- writer.print(Integer.toHexString(System.identityHashCode(this)));
- writer.println(" State:");
- String innerPrefix = prefix + " ";
- writer.print(innerPrefix); writer.print("mCreated=");
- writer.print(mCreated); writer.print("mResumed=");
- writer.print(mResumed); writer.print(" mStopped=");
- writer.print(mStopped); writer.print(" mReallyStopped=");
- writer.println(mReallyStopped);
- writer.print(innerPrefix); writer.print("mLoadersStarted=");
- writer.println(mLoadersStarted);
- if (mLoaderManager != null) {
- writer.print(prefix); writer.print("Loader Manager ");
- writer.print(Integer.toHexString(System.identityHashCode(mLoaderManager)));
- writer.println(":");
- mLoaderManager.dump(prefix + " ", fd, writer, args);
- }
- mFragments.dump(prefix, fd, writer, args);
- }
-
- void doReallyStop(boolean retaining) {
- if (!mReallyStopped) {
- mReallyStopped = true;
- mRetaining = retaining;
- mHandler.removeMessages(MSG_REALLY_STOPPED);
- onReallyStop();
- }
- }
-
- /**
- * Pre-HC, we didn't have a way to determine whether an activity was
- * being stopped for a config change or not until we saw
- * onRetainNonConfigurationInstance() called after onStop(). However
- * we need to know this, to know whether to retain fragments. This will
- * tell us what we need to know.
- */
- void onReallyStop() {
- if (mLoadersStarted) {
- mLoadersStarted = false;
- if (mLoaderManager != null) {
- if (!mRetaining) {
- mLoaderManager.doStop();
- } else {
- mLoaderManager.doRetain();
- }
- }
- }
-
- mFragments.dispatchReallyStop();
- }
-
- // ------------------------------------------------------------------------
- // ACTION BAR AND ACTION MODE SUPPORT
- // ------------------------------------------------------------------------
-
- /**
- * Retrieve a reference to this activity's action bar handler.
- *
- * @return The handler for the appropriate action bar, or null.
- */
- @Override
- public ActionBar getSupportActionBar() {
- initActionBar();
- return mActionBar;
- }
-
- /**
- * Notifies the activity that an action mode has finished. Activity
- * subclasses overriding this method should call the superclass
- * implementation.
- *
- * @param mode The action mode that just finished.
- */
- @Override
- public void onActionModeFinished(ActionMode mode) {
- }
-
- /**
- * Notifies the Activity that an action mode has been started. Activity
- * subclasses overriding this method should call the superclass
- * implementation.
- *
- * @param mode The new action mode.
- */
- @Override
- public void onActionModeStarted(ActionMode mode) {
- }
-
- /**
- * Give the Activity a chance to control the UI for an action mode
- * requested by the system.
- *
- * Note: If you are looking for a notification callback that an action
- * mode has been started for this activity, see
- * {@link #onActionModeStarted(ActionMode)}.
- *
- * @param callback The callback that should control the new action mode
- * @return The new action mode, or null if the activity does not want to
- * provide special handling for this action mode. (It will be handled by the
- * system.)
- */
- @Override
- public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) {
- return null;
- }
-
- /**
- * Start an action mode.
- *
- * @param callback Callback that will manage lifecycle events for this
- * context mode
- * @return The ContextMode that was started, or null if it was cancelled
- * @see android.support.v4.view.ActionMode
- */
- @Override
- public final ActionMode startActionMode(final ActionMode.Callback callback) {
- //Give the activity override a chance to handle the action mode
- ActionMode actionMode = onWindowStartingActionMode(callback);
-
- if (actionMode == null) {
- //If the activity did not handle, send to action bar for platform-
- //specific implementation
- actionMode = mActionBar.startActionMode(callback);
- }
- if (actionMode != null) {
- //Send the activity callback that our action mode was started
- onActionModeStarted(actionMode);
- }
-
- //Return to the caller
- return actionMode;
- }
-
- // ------------------------------------------------------------------------
- // FRAGMENT SUPPORT
- // ------------------------------------------------------------------------
-
- /**
- * Called when a fragment is attached to the activity.
- */
- @Override
- public void onAttachFragment(Fragment fragment) {
- }
-
- /**
- * Return the FragmentManager for interacting with fragments associated
- * with this activity.
- */
- @Override
- public FragmentManager getSupportFragmentManager() {
- //PLEASE let no one be dumb enough to call this too soon...
- initActionBar();
- return mFragments;
- }
-
- /**
- * Modifies the standard behavior to allow results to be delivered to fragments.
- * This imposes a restriction that requestCode be <= 0xffff.
- */
- @Override
- public void startActivityForResult(Intent intent, int requestCode) {
- if (requestCode != -1 && (requestCode&0xffff0000) != 0) {
- throw new IllegalArgumentException("Can only use lower 16 bits for requestCode");
- }
- super.startActivityForResult(intent, requestCode);
- }
-
- /**
- * Called by Fragment.startActivityForResult() to implement its behavior.
- */
- @Override
- public void startActivityFromFragment(Fragment fragment, Intent intent,
- int requestCode) {
- if (requestCode == -1) {
- super.startActivityForResult(intent, -1);
- return;
- }
- if ((requestCode&0xffff0000) != 0) {
- throw new IllegalArgumentException("Can only use lower 16 bits for requestCode");
- }
- super.startActivityForResult(intent, ((fragment.mIndex+1)<<16) + (requestCode&0xffff));
- }
-
- void invalidateSupportFragmentIndex(int index) {
- //Log.v(TAG, "invalidateFragmentIndex: index=" + index);
- if (mAllLoaderManagers != null) {
- LoaderManagerImpl lm = mAllLoaderManagers.get(index);
- if (lm != null && !lm.mRetaining) {
- lm.doDestroy();
- mAllLoaderManagers.remove(index);
- }
- }
- }
-
- // ------------------------------------------------------------------------
- // LOADER SUPPORT
- // ------------------------------------------------------------------------
-
- /**
- * Return the LoaderManager for this fragment, creating it if needed.
- */
- @Override
- public LoaderManager getSupportLoaderManager() {
- if (mLoaderManager != null) {
- return mLoaderManager;
- }
- mCheckedForLoaderManager = true;
- mLoaderManager = getLoaderManager(-1, mLoadersStarted, true);
- return mLoaderManager;
- }
-
- LoaderManagerImpl getLoaderManager(int index, boolean started, boolean create) {
- if (mAllLoaderManagers == null) {
- mAllLoaderManagers = new HCSparseArray();
- }
- LoaderManagerImpl lm = mAllLoaderManagers.get(index);
- if (lm == null) {
- if (create) {
- lm = new LoaderManagerImpl(this, started);
- mAllLoaderManagers.put(index, lm);
- }
- } else {
- lm.updateActivity(this);
- }
- return lm;
- }
-}
diff --git a/actionbarsherlock/library/src/android/support/v4/app/FragmentManager.java b/actionbarsherlock/library/src/android/support/v4/app/FragmentManager.java
deleted file mode 100644
index 6ad062764..000000000
--- a/actionbarsherlock/library/src/android/support/v4/app/FragmentManager.java
+++ /dev/null
@@ -1,1992 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v4.app;
-
-import android.content.Context;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.support.v4.util.DebugUtils;
-import android.support.v4.util.LogWriter;
-import android.support.v4.view.Menu;
-import android.support.v4.view.MenuItem;
-import android.util.Log;
-import android.util.SparseArray;
-import android.view.animation.AccelerateInterpolator;
-import android.view.animation.AlphaAnimation;
-import android.view.animation.Animation;
-import android.view.animation.AnimationSet;
-import android.view.animation.AnimationUtils;
-import android.view.animation.DecelerateInterpolator;
-import android.view.animation.Interpolator;
-import android.view.animation.ScaleAnimation;
-import android.view.animation.Animation.AnimationListener;
-import android.view.MenuInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-/**
- * Static library support version of the framework's {@link android.app.FragmentManager}.
- * Used to write apps that run on platforms prior to Android 3.0. When running
- * on Android 3.0 or above, this implementation is still used; it does not try
- * to switch to the framework's implementation. See the framework SDK
- * documentation for a class overview.
- *
- * Your activity must derive from {@link FragmentActivity} to use this.
- */
-public abstract class FragmentManager {
- /**
- * Representation of an entry on the fragment back stack, as created
- * with {@link FragmentTransaction#addToBackStack(String)
- * FragmentTransaction.addToBackStack()}. Entries can later be
- * retrieved with {@link FragmentManager#getBackStackEntryAt(int)
- * FragmentManager.getBackStackEntry()}.
- *
- *
Note that you should never hold on to a BackStackEntry object;
- * the identifier as returned by {@link #getId} is the only thing that
- * will be persisted across activity instances.
- */
- public interface BackStackEntry {
- /**
- * Return the unique identifier for the entry. This is the only
- * representation of the entry that will persist across activity
- * instances.
- */
- public int getId();
-
- /**
- * Get the name that was supplied to
- * {@link FragmentTransaction#addToBackStack(String)
- * FragmentTransaction.addToBackStack(String)} when creating this entry.
- */
- public String getName();
-
- /**
- * Return the full bread crumb title resource identifier for the entry,
- * or 0 if it does not have one.
- */
- public int getBreadCrumbTitleRes();
-
- /**
- * Return the short bread crumb title resource identifier for the entry,
- * or 0 if it does not have one.
- */
- public int getBreadCrumbShortTitleRes();
-
- /**
- * Return the full bread crumb title for the entry, or null if it
- * does not have one.
- */
- public CharSequence getBreadCrumbTitle();
-
- /**
- * Return the short bread crumb title for the entry, or null if it
- * does not have one.
- */
- public CharSequence getBreadCrumbShortTitle();
- }
-
- /**
- * Interface to watch for changes to the back stack.
- */
- public interface OnBackStackChangedListener {
- /**
- * Called whenever the contents of the back stack change.
- */
- public void onBackStackChanged();
- }
-
- /**
- * Start a series of edit operations on the Fragments associated with
- * this FragmentManager.
- *
- *
Note: A fragment transaction can only be created/committed prior
- * to an activity saving its state. If you try to commit a transaction
- * after {@link FragmentActivity#onSaveInstanceState FragmentActivity.onSaveInstanceState()}
- * (and prior to a following {@link FragmentActivity#onStart FragmentActivity.onStart}
- * or {@link FragmentActivity#onResume FragmentActivity.onResume()}, you will get an error.
- * This is because the framework takes care of saving your current fragments
- * in the state, and if changes are made after the state is saved then they
- * will be lost.
- */
- public abstract FragmentTransaction beginTransaction();
-
- /** @hide -- remove once prebuilts are in. */
- @Deprecated
- public FragmentTransaction openTransaction() {
- return beginTransaction();
- }
-
- /**
- * After a {@link FragmentTransaction} is committed with
- * {@link FragmentTransaction#commit FragmentTransaction.commit()}, it
- * is scheduled to be executed asynchronously on the process's main thread.
- * If you want to immediately executing any such pending operations, you
- * can call this function (only from the main thread) to do so. Note that
- * all callbacks and other related behavior will be done from within this
- * call, so be careful about where this is called from.
- *
- * @return Returns true if there were any pending transactions to be
- * executed.
- */
- public abstract boolean executePendingTransactions();
-
- /**
- * Finds a fragment that was identified by the given id either when inflated
- * from XML or as the container ID when added in a transaction. This first
- * searches through fragments that are currently added to the manager's
- * activity; if no such fragment is found, then all fragments currently
- * on the back stack associated with this ID are searched.
- * @return The fragment if found or null otherwise.
- */
- public abstract Fragment findFragmentById(int id);
-
- /**
- * Finds a fragment that was identified by the given tag either when inflated
- * from XML or as supplied when added in a transaction. This first
- * searches through fragments that are currently added to the manager's
- * activity; if no such fragment is found, then all fragments currently
- * on the back stack are searched.
- * @return The fragment if found or null otherwise.
- */
- public abstract Fragment findFragmentByTag(String tag);
-
- /**
- * Flag for {@link #popBackStack(String, int)}
- * and {@link #popBackStack(int, int)}: If set, and the name or ID of
- * a back stack entry has been supplied, then all matching entries will
- * be consumed until one that doesn't match is found or the bottom of
- * the stack is reached. Otherwise, all entries up to but not including that entry
- * will be removed.
- */
- public static final int POP_BACK_STACK_INCLUSIVE = 1<<0;
-
- /**
- * Pop the top state off the back stack. Returns true if there was one
- * to pop, else false. This function is asynchronous -- it enqueues the
- * request to pop, but the action will not be performed until the application
- * returns to its event loop.
- */
- public abstract void popBackStack();
-
- /**
- * Like {@link #popBackStack()}, but performs the operation immediately
- * inside of the call. This is like calling {@link #executePendingTransactions()}
- * afterwards.
- * @return Returns true if there was something popped, else false.
- */
- public abstract boolean popBackStackImmediate();
-
- /**
- * Pop the last fragment transition from the manager's fragment
- * back stack. If there is nothing to pop, false is returned.
- * This function is asynchronous -- it enqueues the
- * request to pop, but the action will not be performed until the application
- * returns to its event loop.
- *
- * @param name If non-null, this is the name of a previous back state
- * to look for; if found, all states up to that state will be popped. The
- * {@link #POP_BACK_STACK_INCLUSIVE} flag can be used to control whether
- * the named state itself is popped. If null, only the top state is popped.
- * @param flags Either 0 or {@link #POP_BACK_STACK_INCLUSIVE}.
- */
- public abstract void popBackStack(String name, int flags);
-
- /**
- * Like {@link #popBackStack(String, int)}, but performs the operation immediately
- * inside of the call. This is like calling {@link #executePendingTransactions()}
- * afterwards.
- * @return Returns true if there was something popped, else false.
- */
- public abstract boolean popBackStackImmediate(String name, int flags);
-
- /**
- * Pop all back stack states up to the one with the given identifier.
- * This function is asynchronous -- it enqueues the
- * request to pop, but the action will not be performed until the application
- * returns to its event loop.
- *
- * @param id Identifier of the stated to be popped. If no identifier exists,
- * false is returned.
- * The identifier is the number returned by
- * {@link FragmentTransaction#commit() FragmentTransaction.commit()}. The
- * {@link #POP_BACK_STACK_INCLUSIVE} flag can be used to control whether
- * the named state itself is popped.
- * @param flags Either 0 or {@link #POP_BACK_STACK_INCLUSIVE}.
- */
- public abstract void popBackStack(int id, int flags);
-
- /**
- * Like {@link #popBackStack(int, int)}, but performs the operation immediately
- * inside of the call. This is like calling {@link #executePendingTransactions()}
- * afterwards.
- * @return Returns true if there was something popped, else false.
- */
- public abstract boolean popBackStackImmediate(int id, int flags);
-
- /**
- * Return the number of entries currently in the back stack.
- */
- public abstract int getBackStackEntryCount();
-
- /**
- * Return the BackStackEntry at index index in the back stack;
- * entries start index 0 being the bottom of the stack.
- */
- public abstract BackStackEntry getBackStackEntryAt(int index);
-
- /**
- * Add a new listener for changes to the fragment back stack.
- */
- public abstract void addOnBackStackChangedListener(OnBackStackChangedListener listener);
-
- /**
- * Remove a listener that was previously added with
- * {@link #addOnBackStackChangedListener(OnBackStackChangedListener)}.
- */
- public abstract void removeOnBackStackChangedListener(OnBackStackChangedListener listener);
-
- /**
- * Put a reference to a fragment in a Bundle. This Bundle can be
- * persisted as saved state, and when later restoring
- * {@link #getFragment(Bundle, String)} will return the current
- * instance of the same fragment.
- *
- * @param bundle The bundle in which to put the fragment reference.
- * @param key The name of the entry in the bundle.
- * @param fragment The Fragment whose reference is to be stored.
- */
- public abstract void putFragment(Bundle bundle, String key, Fragment fragment);
-
- /**
- * Retrieve the current Fragment instance for a reference previously
- * placed with {@link #putFragment(Bundle, String, Fragment)}.
- *
- * @param bundle The bundle from which to retrieve the fragment reference.
- * @param key The name of the entry in the bundle.
- * @return Returns the current Fragment instance that is associated with
- * the given reference.
- */
- public abstract Fragment getFragment(Bundle bundle, String key);
-
- /**
- * Save the current instance state of the given Fragment. This can be
- * used later when creating a new instance of the Fragment and adding
- * it to the fragment manager, to have it create itself to match the
- * current state returned here. Note that there are limits on how
- * this can be used:
- *
- *
- * - The Fragment must currently be attached to the FragmentManager.
- *
- A new Fragment created using this saved state must be the same class
- * type as the Fragment it was created from.
- *
- The saved state can not contain dependencies on other fragments --
- * that is it can't use {@link #putFragment(Bundle, String, Fragment)} to
- * store a fragment reference because that reference may not be valid when
- * this saved state is later used. Likewise the Fragment's target and
- * result code are not included in this state.
- *
- *
- * @param f The Fragment whose state is to be saved.
- * @return The generated state. This will be null if there was no
- * interesting state created by the fragment.
- */
- public abstract Fragment.SavedState saveFragmentInstanceState(Fragment f);
-
- /**
- * Print the FragmentManager's state into the given stream.
- *
- * @param prefix Text to print at the front of each line.
- * @param fd The raw file descriptor that the dump is being sent to.
- * @param writer A PrintWriter to which the dump is to be set.
- * @param args Additional arguments to the dump request.
- */
- public abstract void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args);
-
- /**
- * Control whether the framework's internal fragment manager debugging
- * logs are turned on. If enabled, you will see output in logcat as
- * the framework performs fragment operations.
- */
- public static void enableDebugLogging(boolean enabled) {
- FragmentManagerImpl.DEBUG = enabled;
- }
-}
-
-final class FragmentManagerState implements Parcelable {
- FragmentState[] mActive;
- int[] mAdded;
- BackStackState[] mBackStack;
-
- public FragmentManagerState() {
- }
-
- public FragmentManagerState(Parcel in) {
- mActive = in.createTypedArray(FragmentState.CREATOR);
- mAdded = in.createIntArray();
- mBackStack = in.createTypedArray(BackStackState.CREATOR);
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeTypedArray(mActive, flags);
- dest.writeIntArray(mAdded);
- dest.writeTypedArray(mBackStack, flags);
- }
-
- public static final Parcelable.Creator CREATOR
- = new Parcelable.Creator() {
- public FragmentManagerState createFromParcel(Parcel in) {
- return new FragmentManagerState(in);
- }
-
- public FragmentManagerState[] newArray(int size) {
- return new FragmentManagerState[size];
- }
- };
-}
-
-/**
- * Container for fragments associated with an activity.
- */
-final class FragmentManagerImpl extends FragmentManager {
- static boolean DEBUG = false;
- static final String TAG = "FragmentManager";
-
- static final boolean HONEYCOMB = android.os.Build.VERSION.SDK_INT >= 11;
-
- static final String TARGET_REQUEST_CODE_STATE_TAG = "android:target_req_state";
- static final String TARGET_STATE_TAG = "android:target_state";
- static final String VIEW_STATE_TAG = "android:view_state";
- static final String USER_VISIBLE_HINT_TAG = "android:user_visible_hint";
-
- ArrayList mPendingActions;
- Runnable[] mTmpActions;
- boolean mExecutingActions;
-
- ArrayList mActive;
- ArrayList mAdded;
- ArrayList mAvailIndices;
- ArrayList mBackStack;
- ArrayList mCreatedMenus;
-
- // Must be accessed while locked.
- ArrayList mBackStackIndices;
- ArrayList mAvailBackStackIndices;
-
- ArrayList mBackStackChangeListeners;
-
- int mCurState = Fragment.INITIALIZING;
- SupportActivity mActivity;
-
- boolean mNeedMenuInvalidate;
- boolean mStateSaved;
- boolean mDestroyed;
- String mNoTransactionsBecause;
- boolean mHavePendingDeferredStart;
-
- // Temporary vars for state save and restore.
- Bundle mStateBundle = null;
- SparseArray mStateArray = null;
-
- Runnable mExecCommit = new Runnable() {
- @Override
- public void run() {
- execPendingActions();
- }
- };
-
- @Override
- public FragmentTransaction beginTransaction() {
- return new BackStackRecord(this);
- }
-
- @Override
- public boolean executePendingTransactions() {
- return execPendingActions();
- }
-
- @Override
- public void popBackStack() {
- enqueueAction(new Runnable() {
- @Override public void run() {
- popBackStackState(mActivity.getInternalCallbacks().getHandler(), null, -1, 0);
- }
- }, false);
- }
-
- @Override
- public boolean popBackStackImmediate() {
- checkStateLoss();
- executePendingTransactions();
- return popBackStackState(mActivity.getInternalCallbacks().getHandler(), null, -1, 0);
- }
-
- @Override
- public void popBackStack(final String name, final int flags) {
- enqueueAction(new Runnable() {
- @Override public void run() {
- popBackStackState(mActivity.getInternalCallbacks().getHandler(), name, -1, flags);
- }
- }, false);
- }
-
- @Override
- public boolean popBackStackImmediate(String name, int flags) {
- checkStateLoss();
- executePendingTransactions();
- return popBackStackState(mActivity.getInternalCallbacks().getHandler(), name, -1, flags);
- }
-
- @Override
- public void popBackStack(final int id, final int flags) {
- if (id < 0) {
- throw new IllegalArgumentException("Bad id: " + id);
- }
- enqueueAction(new Runnable() {
- @Override public void run() {
- popBackStackState(mActivity.getInternalCallbacks().getHandler(), null, id, flags);
- }
- }, false);
- }
-
- @Override
- public boolean popBackStackImmediate(int id, int flags) {
- checkStateLoss();
- executePendingTransactions();
- if (id < 0) {
- throw new IllegalArgumentException("Bad id: " + id);
- }
- return popBackStackState(mActivity.getInternalCallbacks().getHandler(), null, id, flags);
- }
-
- @Override
- public int getBackStackEntryCount() {
- return mBackStack != null ? mBackStack.size() : 0;
- }
-
- @Override
- public BackStackEntry getBackStackEntryAt(int index) {
- return mBackStack.get(index);
- }
-
- @Override
- public void addOnBackStackChangedListener(OnBackStackChangedListener listener) {
- if (mBackStackChangeListeners == null) {
- mBackStackChangeListeners = new ArrayList();
- }
- mBackStackChangeListeners.add(listener);
- }
-
- @Override
- public void removeOnBackStackChangedListener(OnBackStackChangedListener listener) {
- if (mBackStackChangeListeners != null) {
- mBackStackChangeListeners.remove(listener);
- }
- }
-
- @Override
- public void putFragment(Bundle bundle, String key, Fragment fragment) {
- if (fragment.mIndex < 0) {
- throw new IllegalStateException("Fragment " + fragment
- + " is not currently in the FragmentManager");
- }
- bundle.putInt(key, fragment.mIndex);
- }
-
- @Override
- public Fragment getFragment(Bundle bundle, String key) {
- int index = bundle.getInt(key, -1);
- if (index == -1) {
- return null;
- }
- if (index >= mActive.size()) {
- throw new IllegalStateException("Fragement no longer exists for key "
- + key + ": index " + index);
- }
- Fragment f = mActive.get(index);
- if (f == null) {
- throw new IllegalStateException("Fragement no longer exists for key "
- + key + ": index " + index);
- }
- return f;
- }
-
- @Override
- public Fragment.SavedState saveFragmentInstanceState(Fragment fragment) {
- if (fragment.mIndex < 0) {
- throw new IllegalStateException("Fragment " + fragment
- + " is not currently in the FragmentManager");
- }
- if (fragment.mState > Fragment.INITIALIZING) {
- Bundle result = saveFragmentBasicState(fragment);
- return result != null ? new Fragment.SavedState(result) : null;
- }
- return null;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder(128);
- sb.append("FragmentManager{");
- sb.append(Integer.toHexString(System.identityHashCode(this)));
- sb.append(" in ");
- DebugUtils.buildShortClassTag(mActivity, sb);
- sb.append("}}");
- return sb.toString();
- }
-
- @Override
- public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
- String innerPrefix = prefix + " ";
-
- int N;
- if (mActive != null) {
- N = mActive.size();
- if (N > 0) {
- writer.print(prefix); writer.print("Active Fragments in ");
- writer.print(Integer.toHexString(System.identityHashCode(this)));
- writer.println(":");
- for (int i=0; i 0) {
- writer.print(prefix); writer.println("Added Fragments:");
- for (int i=0; i 0) {
- writer.print(prefix); writer.println("Fragments Created Menus:");
- for (int i=0; i 0) {
- writer.print(prefix); writer.println("Back Stack:");
- for (int i=0; i 0) {
- writer.print(prefix); writer.println("Back Stack Indices:");
- for (int i=0; i 0) {
- writer.print(prefix); writer.print("mAvailBackStackIndices: ");
- writer.println(Arrays.toString(mAvailBackStackIndices.toArray()));
- }
- }
-
- if (mPendingActions != null) {
- N = mPendingActions.size();
- if (N > 0) {
- writer.print(prefix); writer.println("Pending Actions:");
- for (int i=0; i Fragment.CREATED) {
- newState = Fragment.CREATED;
- }
- if (f.mRemoving && newState > f.mState) {
- // While removing a fragment, we can't change it to a higher state.
- newState = f.mState;
- }
- // Defer start if requested; don't allow it to move to STARTED or higher
- // if it's not already started.
- if (f.mDeferStart && f.mState < Fragment.STARTED && newState > Fragment.STOPPED) {
- newState = Fragment.STOPPED;
- }
- if (f.mState < newState) {
- // For fragments that are created from a layout, when restoring from
- // state we don't want to allow them to be created until they are
- // being reloaded from the layout.
- if (f.mFromLayout && !f.mInLayout) {
- return;
- }
- if (f.mAnimatingAway != null) {
- // The fragment is currently being animated... but! Now we
- // want to move our state back up. Give up on waiting for the
- // animation, move to whatever the final state should be once
- // the animation is done, and then we can proceed from there.
- f.mAnimatingAway = null;
- moveToState(f, f.mStateAfterAnimating, 0, 0);
- }
- switch (f.mState) {
- case Fragment.INITIALIZING:
- if (DEBUG) Log.v(TAG, "moveto CREATED: " + f);
- if (f.mSavedFragmentState != null) {
- f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray(
- FragmentManagerImpl.VIEW_STATE_TAG);
- f.mTarget = getFragment(f.mSavedFragmentState,
- FragmentManagerImpl.TARGET_STATE_TAG);
- if (f.mTarget != null) {
- f.mTargetRequestCode = f.mSavedFragmentState.getInt(
- FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0);
- }
- f.mUserVisibleHint = f.mSavedFragmentState.getBoolean(
- FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true);
- if (!f.mUserVisibleHint) {
- f.mDeferStart = true;
- if (newState > Fragment.STOPPED) {
- newState = Fragment.STOPPED;
- }
- }
- }
- f.mActivity = mActivity;
- f.mFragmentManager = mActivity.getInternalCallbacks().getFragments();
- f.mCalled = false;
- f.onAttach(mActivity);
- if (!f.mCalled) {
- throw new SuperNotCalledException("Fragment " + f
- + " did not call through to super.onAttach()");
- }
- mActivity.onAttachFragment(f);
-
- if (!f.mRetaining) {
- f.mCalled = false;
- f.onCreate(f.mSavedFragmentState);
- if (!f.mCalled) {
- throw new SuperNotCalledException("Fragment " + f
- + " did not call through to super.onCreate()");
- }
- }
- f.mRetaining = false;
- if (f.mFromLayout) {
- // For fragments that are part of the content view
- // layout, we need to instantiate the view immediately
- // and the inflater will take care of adding it.
- f.mView = f.onCreateView(f.getLayoutInflater(f.mSavedFragmentState),
- null, f.mSavedFragmentState);
- if (f.mView != null) {
- f.mInnerView = f.mView;
- f.mView = NoSaveStateFrameLayout.wrap(f.mView);
- if (f.mHidden) f.mView.setVisibility(View.GONE);
- f.onViewCreated(f.mView, f.mSavedFragmentState);
- } else {
- f.mInnerView = null;
- }
- }
- case Fragment.CREATED:
- if (newState > Fragment.CREATED) {
- if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f);
- if (!f.mFromLayout) {
- ViewGroup container = null;
- if (f.mContainerId != 0) {
- container = (ViewGroup)mActivity.findViewById(f.mContainerId);
- if (container == null && !f.mRestored) {
- throw new IllegalArgumentException("No view found for id 0x"
- + Integer.toHexString(f.mContainerId)
- + " for fragment " + f);
- }
- }
- f.mContainer = container;
- f.mView = f.onCreateView(f.getLayoutInflater(f.mSavedFragmentState),
- container, f.mSavedFragmentState);
- if (f.mView != null) {
- f.mInnerView = f.mView;
- f.mView = NoSaveStateFrameLayout.wrap(f.mView);
- if (container != null) {
- Animation anim = loadAnimation(f, transit, true,
- transitionStyle);
- if (anim != null) {
- f.mView.startAnimation(anim);
- }
- container.addView(f.mView);
- }
- if (f.mHidden) f.mView.setVisibility(View.GONE);
- f.onViewCreated(f.mView, f.mSavedFragmentState);
- } else {
- f.mInnerView = null;
- }
- }
-
- f.mCalled = false;
- f.onActivityCreated(f.mSavedFragmentState);
- if (!f.mCalled) {
- throw new SuperNotCalledException("Fragment " + f
- + " did not call through to super.onActivityCreated()");
- }
- if (f.mView != null) {
- f.restoreViewState();
- }
- f.mSavedFragmentState = null;
- }
- case Fragment.ACTIVITY_CREATED:
- case Fragment.STOPPED:
- if (newState > Fragment.STOPPED) {
- if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);
- f.mCalled = false;
- f.performStart();
- if (!f.mCalled) {
- throw new SuperNotCalledException("Fragment " + f
- + " did not call through to super.onStart()");
- }
- }
- case Fragment.STARTED:
- if (newState > Fragment.STARTED) {
- if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f);
- f.mCalled = false;
- f.mResumed = true;
- f.onResume();
- if (!f.mCalled) {
- throw new SuperNotCalledException("Fragment " + f
- + " did not call through to super.onResume()");
- }
- f.mSavedFragmentState = null;
- f.mSavedViewState = null;
- }
- }
- } else if (f.mState > newState) {
- switch (f.mState) {
- case Fragment.RESUMED:
- if (newState < Fragment.RESUMED) {
- if (DEBUG) Log.v(TAG, "movefrom RESUMED: " + f);
- f.mCalled = false;
- f.onPause();
- if (!f.mCalled) {
- throw new SuperNotCalledException("Fragment " + f
- + " did not call through to super.onPause()");
- }
- f.mResumed = false;
- }
- case Fragment.STARTED:
- if (newState < Fragment.STARTED) {
- if (DEBUG) Log.v(TAG, "movefrom STARTED: " + f);
- f.mCalled = false;
- f.performStop();
- if (!f.mCalled) {
- throw new SuperNotCalledException("Fragment " + f
- + " did not call through to super.onStop()");
- }
- }
- case Fragment.STOPPED:
- if (newState < Fragment.STOPPED) {
- if (DEBUG) Log.v(TAG, "movefrom STOPPED: " + f);
- f.performReallyStop();
- }
- case Fragment.ACTIVITY_CREATED:
- if (newState < Fragment.ACTIVITY_CREATED) {
- if (DEBUG) Log.v(TAG, "movefrom ACTIVITY_CREATED: " + f);
- if (f.mView != null) {
- // Need to save the current view state if not
- // done already.
- if (!mActivity.isFinishing() && f.mSavedViewState == null) {
- saveFragmentViewState(f);
- }
- }
- f.mCalled = false;
- f.performDestroyView();
- if (!f.mCalled) {
- throw new SuperNotCalledException("Fragment " + f
- + " did not call through to super.onDestroyView()");
- }
- if (f.mView != null && f.mContainer != null) {
- Animation anim = null;
- if (mCurState > Fragment.INITIALIZING && !mDestroyed) {
- anim = loadAnimation(f, transit, false,
- transitionStyle);
- }
- if (anim != null) {
- final Fragment fragment = f;
- f.mAnimatingAway = f.mView;
- f.mStateAfterAnimating = newState;
- anim.setAnimationListener(new AnimationListener() {
- @Override
- public void onAnimationEnd(Animation animation) {
- if (fragment.mAnimatingAway != null) {
- fragment.mAnimatingAway = null;
- moveToState(fragment, fragment.mStateAfterAnimating,
- 0, 0);
- }
- }
- @Override
- public void onAnimationRepeat(Animation animation) {
- }
- @Override
- public void onAnimationStart(Animation animation) {
- }
- });
- f.mView.startAnimation(anim);
- }
- f.mContainer.removeView(f.mView);
- }
- f.mContainer = null;
- f.mView = null;
- f.mInnerView = null;
- }
- case Fragment.CREATED:
- if (newState < Fragment.CREATED) {
- if (mDestroyed) {
- if (f.mAnimatingAway != null) {
- // The fragment's containing activity is
- // being destroyed, but this fragment is
- // currently animating away. Stop the
- // animation right now -- it is not needed,
- // and we can't wait any more on destroying
- // the fragment.
- View v = f.mAnimatingAway;
- f.mAnimatingAway = null;
- v.clearAnimation();
- }
- }
- if (f.mAnimatingAway != null) {
- // We are waiting for the fragment's view to finish
- // animating away. Just make a note of the state
- // the fragment now should move to once the animation
- // is done.
- f.mStateAfterAnimating = newState;
- newState = Fragment.CREATED;
- } else {
- if (DEBUG) Log.v(TAG, "movefrom CREATED: " + f);
- if (!f.mRetaining) {
- f.mCalled = false;
- f.onDestroy();
- if (!f.mCalled) {
- throw new SuperNotCalledException("Fragment " + f
- + " did not call through to super.onDestroy()");
- }
- }
-
- f.mCalled = false;
- f.onDetach();
- if (!f.mCalled) {
- throw new SuperNotCalledException("Fragment " + f
- + " did not call through to super.onDetach()");
- }
- if (!f.mRetaining) {
- makeInactive(f);
- } else {
- f.mActivity = null;
- f.mFragmentManager = null;
- }
- }
- }
- }
- }
-
- f.mState = newState;
- }
-
- void moveToState(Fragment f) {
- moveToState(f, mCurState, 0, 0);
- }
-
- void moveToState(int newState, boolean always) {
- moveToState(newState, 0, 0, always);
- }
-
- void moveToState(int newState, int transit, int transitStyle, boolean always) {
- if (mActivity == null && newState != Fragment.INITIALIZING) {
- throw new IllegalStateException("No activity");
- }
-
- if (!always && mCurState == newState) {
- return;
- }
-
- mCurState = newState;
- if (mActive != null) {
- boolean loadersRunning = false;
- for (int i=0; i= 0) {
- return;
- }
-
- if (mAvailIndices == null || mAvailIndices.size() <= 0) {
- if (mActive == null) {
- mActive = new ArrayList();
- }
- f.setIndex(mActive.size());
- mActive.add(f);
-
- } else {
- f.setIndex(mAvailIndices.remove(mAvailIndices.size()-1));
- mActive.set(f.mIndex, f);
- }
- }
-
- void makeInactive(Fragment f) {
- if (f.mIndex < 0) {
- return;
- }
-
- if (DEBUG) Log.v(TAG, "Freeing fragment index " + f.mIndex);
- mActive.set(f.mIndex, null);
- if (mAvailIndices == null) {
- mAvailIndices = new ArrayList();
- }
- mAvailIndices.add(f.mIndex);
- mActivity.getInternalCallbacks().invalidateSupportFragmentIndex(f.mIndex);
- f.initState();
- }
-
- public void addFragment(Fragment fragment, boolean moveToStateNow) {
- if (mAdded == null) {
- mAdded = new ArrayList();
- }
- if (DEBUG) Log.v(TAG, "add: " + fragment);
- makeActive(fragment);
- if (!fragment.mDetached) {
- mAdded.add(fragment);
- fragment.mAdded = true;
- fragment.mRemoving = false;
- if (fragment.mHasMenu && fragment.mMenuVisible) {
- mNeedMenuInvalidate = true;
- }
- if (moveToStateNow) {
- moveToState(fragment);
- }
- }
- }
-
- public void removeFragment(Fragment fragment, int transition, int transitionStyle) {
- if (DEBUG) Log.v(TAG, "remove: " + fragment + " nesting=" + fragment.mBackStackNesting);
- final boolean inactive = !fragment.isInBackStack();
- if (!fragment.mDetached || inactive) {
- mAdded.remove(fragment);
- if (fragment.mHasMenu && fragment.mMenuVisible) {
- mNeedMenuInvalidate = true;
- }
- fragment.mAdded = false;
- fragment.mRemoving = true;
- moveToState(fragment, inactive ? Fragment.INITIALIZING : Fragment.CREATED,
- transition, transitionStyle);
- }
- }
-
- public void hideFragment(Fragment fragment, int transition, int transitionStyle) {
- if (DEBUG) Log.v(TAG, "hide: " + fragment);
- if (!fragment.mHidden) {
- fragment.mHidden = true;
- if (fragment.mView != null) {
- Animation anim = loadAnimation(fragment, transition, true,
- transitionStyle);
- if (anim != null) {
- fragment.mView.startAnimation(anim);
- }
- fragment.mView.setVisibility(View.GONE);
- }
- if (fragment.mAdded && fragment.mHasMenu && fragment.mMenuVisible) {
- mNeedMenuInvalidate = true;
- }
- fragment.onHiddenChanged(true);
- }
- }
-
- public void showFragment(Fragment fragment, int transition, int transitionStyle) {
- if (DEBUG) Log.v(TAG, "show: " + fragment);
- if (fragment.mHidden) {
- fragment.mHidden = false;
- if (fragment.mView != null) {
- Animation anim = loadAnimation(fragment, transition, true,
- transitionStyle);
- if (anim != null) {
- fragment.mView.startAnimation(anim);
- }
- fragment.mView.setVisibility(View.VISIBLE);
- }
- if (fragment.mAdded && fragment.mHasMenu && fragment.mMenuVisible) {
- mNeedMenuInvalidate = true;
- }
- fragment.onHiddenChanged(false);
- }
- }
-
- public void detachFragment(Fragment fragment, int transition, int transitionStyle) {
- if (DEBUG) Log.v(TAG, "detach: " + fragment);
- if (!fragment.mDetached) {
- fragment.mDetached = true;
- if (fragment.mAdded) {
- // We are not already in back stack, so need to remove the fragment.
- mAdded.remove(fragment);
- if (fragment.mHasMenu && fragment.mMenuVisible) {
- mNeedMenuInvalidate = true;
- }
- fragment.mAdded = false;
- moveToState(fragment, Fragment.CREATED, transition, transitionStyle);
- }
- }
- }
-
- public void attachFragment(Fragment fragment, int transition, int transitionStyle) {
- if (DEBUG) Log.v(TAG, "attach: " + fragment);
- if (fragment.mDetached) {
- fragment.mDetached = false;
- if (!fragment.mAdded) {
- mAdded.add(fragment);
- fragment.mAdded = true;
- if (fragment.mHasMenu && fragment.mMenuVisible) {
- mNeedMenuInvalidate = true;
- }
- moveToState(fragment, mCurState, transition, transitionStyle);
- }
- }
- }
-
- public Fragment findFragmentById(int id) {
- if (mActive != null) {
- // First look through added fragments.
- for (int i=mAdded.size()-1; i>=0; i--) {
- Fragment f = mAdded.get(i);
- if (f != null && f.mFragmentId == id) {
- return f;
- }
- }
- // Now for any known fragment.
- for (int i=mActive.size()-1; i>=0; i--) {
- Fragment f = mActive.get(i);
- if (f != null && f.mFragmentId == id) {
- return f;
- }
- }
- }
- return null;
- }
-
- public Fragment findFragmentByTag(String tag) {
- if (mActive != null && tag != null) {
- // First look through added fragments.
- for (int i=mAdded.size()-1; i>=0; i--) {
- Fragment f = mAdded.get(i);
- if (f != null && tag.equals(f.mTag)) {
- return f;
- }
- }
- // Now for any known fragment.
- for (int i=mActive.size()-1; i>=0; i--) {
- Fragment f = mActive.get(i);
- if (f != null && tag.equals(f.mTag)) {
- return f;
- }
- }
- }
- return null;
- }
-
- public Fragment findFragmentByWho(String who) {
- if (mActive != null && who != null) {
- for (int i=mActive.size()-1; i>=0; i--) {
- Fragment f = mActive.get(i);
- if (f != null && who.equals(f.mWho)) {
- return f;
- }
- }
- }
- return null;
- }
-
- private void checkStateLoss() {
- if (mStateSaved) {
- throw new IllegalStateException(
- "Can not perform this action after onSaveInstanceState");
- }
- if (mNoTransactionsBecause != null) {
- throw new IllegalStateException(
- "Can not perform this action inside of " + mNoTransactionsBecause);
- }
- }
-
- public void enqueueAction(Runnable action, boolean allowStateLoss) {
- if (!allowStateLoss) {
- checkStateLoss();
- }
- synchronized (this) {
- if (mActivity == null) {
- throw new IllegalStateException("Activity has been destroyed");
- }
- if (mPendingActions == null) {
- mPendingActions = new ArrayList();
- }
- mPendingActions.add(action);
- if (mPendingActions.size() == 1) {
- mActivity.getInternalCallbacks().getHandler().removeCallbacks(mExecCommit);
- mActivity.getInternalCallbacks().getHandler().post(mExecCommit);
- }
- }
- }
-
- public int allocBackStackIndex(BackStackRecord bse) {
- synchronized (this) {
- if (mAvailBackStackIndices == null || mAvailBackStackIndices.size() <= 0) {
- if (mBackStackIndices == null) {
- mBackStackIndices = new ArrayList();
- }
- int index = mBackStackIndices.size();
- if (DEBUG) Log.v(TAG, "Setting back stack index " + index + " to " + bse);
- mBackStackIndices.add(bse);
- return index;
-
- } else {
- int index = mAvailBackStackIndices.remove(mAvailBackStackIndices.size()-1);
- if (DEBUG) Log.v(TAG, "Adding back stack index " + index + " with " + bse);
- mBackStackIndices.set(index, bse);
- return index;
- }
- }
- }
-
- public void setBackStackIndex(int index, BackStackRecord bse) {
- synchronized (this) {
- if (mBackStackIndices == null) {
- mBackStackIndices = new ArrayList();
- }
- int N = mBackStackIndices.size();
- if (index < N) {
- if (DEBUG) Log.v(TAG, "Setting back stack index " + index + " to " + bse);
- mBackStackIndices.set(index, bse);
- } else {
- while (N < index) {
- mBackStackIndices.add(null);
- if (mAvailBackStackIndices == null) {
- mAvailBackStackIndices = new ArrayList();
- }
- if (DEBUG) Log.v(TAG, "Adding available back stack index " + N);
- mAvailBackStackIndices.add(N);
- N++;
- }
- if (DEBUG) Log.v(TAG, "Adding back stack index " + index + " with " + bse);
- mBackStackIndices.add(bse);
- }
- }
- }
-
- public void freeBackStackIndex(int index) {
- synchronized (this) {
- mBackStackIndices.set(index, null);
- if (mAvailBackStackIndices == null) {
- mAvailBackStackIndices = new ArrayList();
- }
- if (DEBUG) Log.v(TAG, "Freeing back stack index " + index);
- mAvailBackStackIndices.add(index);
- }
- }
-
- /**
- * Only call from main thread!
- */
- public boolean execPendingActions() {
- if (mExecutingActions) {
- throw new IllegalStateException("Recursive entry to executePendingTransactions");
- }
-
- if (Looper.myLooper() != mActivity.getInternalCallbacks().getHandler().getLooper()) {
- throw new IllegalStateException("Must be called from main thread of process");
- }
-
- boolean didSomething = false;
-
- while (true) {
- int numActions;
-
- synchronized (this) {
- if (mPendingActions == null || mPendingActions.size() == 0) {
- break;
- }
-
- numActions = mPendingActions.size();
- if (mTmpActions == null || mTmpActions.length < numActions) {
- mTmpActions = new Runnable[numActions];
- }
- mPendingActions.toArray(mTmpActions);
- mPendingActions.clear();
- mActivity.getInternalCallbacks().getHandler().removeCallbacks(mExecCommit);
- }
-
- mExecutingActions = true;
- for (int i=0; i();
- }
- mBackStack.add(state);
- reportBackStackChanged();
- }
-
- boolean popBackStackState(Handler handler, String name, int id, int flags) {
- if (mBackStack == null) {
- return false;
- }
- if (name == null && id < 0 && (flags&POP_BACK_STACK_INCLUSIVE) == 0) {
- int last = mBackStack.size()-1;
- if (last < 0) {
- return false;
- }
- final BackStackRecord bss = mBackStack.remove(last);
- bss.popFromBackStack(true);
- reportBackStackChanged();
- } else {
- int index = -1;
- if (name != null || id >= 0) {
- // If a name or ID is specified, look for that place in
- // the stack.
- index = mBackStack.size()-1;
- while (index >= 0) {
- BackStackRecord bss = mBackStack.get(index);
- if (name != null && name.equals(bss.getName())) {
- break;
- }
- if (id >= 0 && id == bss.mIndex) {
- break;
- }
- index--;
- }
- if (index < 0) {
- return false;
- }
- if ((flags&POP_BACK_STACK_INCLUSIVE) != 0) {
- index--;
- // Consume all following entries that match.
- while (index >= 0) {
- BackStackRecord bss = mBackStack.get(index);
- if ((name != null && name.equals(bss.getName()))
- || (id >= 0 && id == bss.mIndex)) {
- index--;
- continue;
- }
- break;
- }
- }
- }
- if (index == mBackStack.size()-1) {
- return false;
- }
- final ArrayList states
- = new ArrayList();
- for (int i=mBackStack.size()-1; i>index; i--) {
- states.add(mBackStack.remove(i));
- }
- final int LAST = states.size()-1;
- for (int i=0; i<=LAST; i++) {
- if (DEBUG) Log.v(TAG, "Popping back stack state: " + states.get(i));
- states.get(i).popFromBackStack(i == LAST);
- }
- reportBackStackChanged();
- }
- return true;
- }
-
- ArrayList retainNonConfig() {
- ArrayList fragments = null;
- if (mActive != null) {
- for (int i=0; i();
- }
- fragments.add(f);
- f.mRetaining = true;
- f.mTargetIndex = f.mTarget != null ? f.mTarget.mIndex : -1;
- }
- }
- }
- return fragments;
- }
-
- void saveFragmentViewState(Fragment f) {
- if (f.mInnerView == null) {
- return;
- }
- if (mStateArray == null) {
- mStateArray = new SparseArray();
- } else {
- mStateArray.clear();
- }
- f.mInnerView.saveHierarchyState(mStateArray);
- if (mStateArray.size() > 0) {
- f.mSavedViewState = mStateArray;
- mStateArray = null;
- }
- }
-
- Bundle saveFragmentBasicState(Fragment f) {
- Bundle result = null;
-
- if (mStateBundle == null) {
- mStateBundle = new Bundle();
- }
- f.onSaveInstanceState(mStateBundle);
- if (!mStateBundle.isEmpty()) {
- result = mStateBundle;
- mStateBundle = null;
- }
-
- if (f.mView != null) {
- saveFragmentViewState(f);
- }
- if (f.mSavedViewState != null) {
- if (result == null) {
- result = new Bundle();
- }
- result.putSparseParcelableArray(
- FragmentManagerImpl.VIEW_STATE_TAG, f.mSavedViewState);
- }
- if (!f.mUserVisibleHint) {
- // Only add this if it's not the default value
- result.putBoolean(FragmentManagerImpl.USER_VISIBLE_HINT_TAG, f.mUserVisibleHint);
- }
-
- return result;
- }
-
- Parcelable saveAllState() {
- // Make sure all pending operations have now been executed to get
- // our state update-to-date.
- execPendingActions();
-
- if (HONEYCOMB) {
- // As of Honeycomb, we save state after pausing. Prior to that
- // it is before pausing. With fragments this is an issue, since
- // there are many things you may do after pausing but before
- // stopping that change the fragment state. For those older
- // devices, we will not at this point say that we have saved
- // the state, so we will allow them to continue doing fragment
- // transactions. This retains the same semantics as Honeycomb,
- // though you do have the risk of losing the very most recent state
- // if the process is killed... we'll live with that.
- mStateSaved = true;
- }
-
- if (mActive == null || mActive.size() <= 0) {
- return null;
- }
-
- // First collect all active fragments.
- int N = mActive.size();
- FragmentState[] active = new FragmentState[N];
- boolean haveFragments = false;
- for (int i=0; i Fragment.INITIALIZING && fs.mSavedFragmentState == null) {
- fs.mSavedFragmentState = saveFragmentBasicState(f);
-
- if (f.mTarget != null) {
- if (f.mTarget.mIndex < 0) {
- String msg = "Failure saving state: " + f
- + " has target not in fragment manager: " + f.mTarget;
- Log.e(TAG, msg);
- dump(" ", null, new PrintWriter(new LogWriter(TAG)), new String[] { });
- throw new IllegalStateException(msg);
- }
- if (fs.mSavedFragmentState == null) {
- fs.mSavedFragmentState = new Bundle();
- }
- putFragment(fs.mSavedFragmentState,
- FragmentManagerImpl.TARGET_STATE_TAG, f.mTarget);
- if (f.mTargetRequestCode != 0) {
- fs.mSavedFragmentState.putInt(
- FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG,
- f.mTargetRequestCode);
- }
- }
-
- } else {
- fs.mSavedFragmentState = f.mSavedFragmentState;
- }
-
- if (DEBUG) Log.v(TAG, "Saved state of " + f + ": "
- + fs.mSavedFragmentState);
- }
- }
-
- if (!haveFragments) {
- if (DEBUG) Log.v(TAG, "saveAllState: no fragments!");
- return null;
- }
-
- int[] added = null;
- BackStackState[] backStack = null;
-
- // Build list of currently added fragments.
- if (mAdded != null) {
- N = mAdded.size();
- if (N > 0) {
- added = new int[N];
- for (int i=0; i 0) {
- backStack = new BackStackState[N];
- for (int i=0; i nonConfig) {
- // If there is no saved state at all, then there can not be
- // any nonConfig fragments either, so that is that.
- if (state == null) return;
- FragmentManagerState fms = (FragmentManagerState)state;
- if (fms.mActive == null) return;
-
- // First re-attach any non-config instances we are retaining back
- // to their saved state, so we don't try to instantiate them again.
- if (nonConfig != null) {
- for (int i=0; i(fms.mActive.length);
- if (mAvailIndices != null) {
- mAvailIndices.clear();
- }
- for (int i=0; i();
- }
- if (DEBUG) Log.v(TAG, "restoreAllState: adding avail #" + i);
- mAvailIndices.add(i);
- }
- }
-
- // Update the target of all retained fragments.
- if (nonConfig != null) {
- for (int i=0; i= 0) {
- if (f.mTargetIndex < mActive.size()) {
- f.mTarget = mActive.get(f.mTargetIndex);
- } else {
- Log.w(TAG, "Re-attaching retained fragment " + f
- + " target no longer exists: " + f.mTargetIndex);
- f.mTarget = null;
- }
- }
- }
- }
-
- // Build the list of currently added fragments.
- if (fms.mAdded != null) {
- mAdded = new ArrayList(fms.mAdded.length);
- for (int i=0; i(fms.mBackStack.length);
- for (int i=0; i= 0) {
- setBackStackIndex(bse.mIndex, bse);
- }
- }
- } else {
- mBackStack = null;
- }
- }
-
- public void attachActivity(SupportActivity activity) {
- if (mActivity != null) throw new IllegalStateException();
- mActivity = activity;
- }
-
- public void noteStateNotSaved() {
- mStateSaved = false;
- }
-
- public void dispatchCreate() {
- mStateSaved = false;
- moveToState(Fragment.CREATED, false);
- }
-
- public void dispatchActivityCreated() {
- mStateSaved = false;
- moveToState(Fragment.ACTIVITY_CREATED, false);
- }
-
- public void dispatchStart() {
- mStateSaved = false;
- moveToState(Fragment.STARTED, false);
- }
-
- public void dispatchResume() {
- mStateSaved = false;
- moveToState(Fragment.RESUMED, false);
- }
-
- public void dispatchPause() {
- moveToState(Fragment.STARTED, false);
- }
-
- public void dispatchStop() {
- // See saveAllState() for the explanation of this. We do this for
- // all platform versions, to keep our behavior more consistent between
- // them.
- mStateSaved = true;
-
- moveToState(Fragment.STOPPED, false);
- }
-
- public void dispatchReallyStop() {
- moveToState(Fragment.ACTIVITY_CREATED, false);
- }
-
- public void dispatchDestroy() {
- mDestroyed = true;
- execPendingActions();
- moveToState(Fragment.INITIALIZING, false);
- mActivity = null;
- }
-
- public void dispatchConfigurationChanged(Configuration newConfig) {
- if (mActive != null) {
- for (int i=0; i newMenus = null;
- if (mActive != null) {
- for (int i=0; i();
- }
- newMenus.add(f);
- }
- }
- }
-
- if (mCreatedMenus != null) {
- for (int i=0; iThis version of the pager is best for use when there are a handful of
- * typically more static fragments to be paged through, such as a set of tabs.
- * The fragment of each page the user visits will be kept in memory, though its
- * view hierarchy may be destroyed when not visible. This can result in using
- * a significant amount of memory since fragment instances can hold on to an
- * arbitrary amount of state. For larger sets of pages, consider
- * {@link FragmentStatePagerAdapter}.
- *
- * When using FragmentPagerAdapter the host ViewPager must have a
- * valid ID set.
- *
- * Subclasses only need to implement {@link #getItem(int)}
- * and {@link #getCount()} to have a working adapter.
- *
- *
Here is an example implementation of a pager containing fragments of
- * lists:
- *
- * {@sample development/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentPagerSupport.java
- * complete}
- *
- *
The R.layout.fragment_pager
resource of the top-level fragment is:
- *
- * {@sample development/samples/Support4Demos/res/layout/fragment_pager.xml
- * complete}
- *
- *
The R.layout.fragment_pager_list
resource containing each
- * individual fragment's layout is:
- *
- * {@sample development/samples/Support4Demos/res/layout/fragment_pager_list.xml
- * complete}
- */
-public abstract class FragmentPagerAdapter extends PagerAdapter {
- private static final String TAG = "FragmentPagerAdapter";
- private static final boolean DEBUG = false;
-
- private final FragmentManager mFragmentManager;
- private FragmentTransaction mCurTransaction = null;
- private Fragment mCurrentPrimaryItem = null;
-
- public FragmentPagerAdapter(FragmentManager fm) {
- mFragmentManager = fm;
- }
-
- /**
- * Return the Fragment associated with a specified position.
- */
- public abstract Fragment getItem(int position);
-
- @Override
- public void startUpdate(ViewGroup container) {
- }
-
- @Override
- public Object instantiateItem(ViewGroup container, int position) {
- if (mCurTransaction == null) {
- mCurTransaction = mFragmentManager.beginTransaction();
- }
-
- // Do we already have this fragment?
- String name = makeFragmentName(container.getId(), position);
- Fragment fragment = mFragmentManager.findFragmentByTag(name);
- if (fragment != null) {
- if (DEBUG) Log.v(TAG, "Attaching item #" + position + ": f=" + fragment);
- mCurTransaction.attach(fragment);
- } else {
- fragment = getItem(position);
- if (DEBUG) Log.v(TAG, "Adding item #" + position + ": f=" + fragment);
- mCurTransaction.add(container.getId(), fragment,
- makeFragmentName(container.getId(), position));
- }
- if (fragment != mCurrentPrimaryItem) {
- fragment.setMenuVisibility(false);
- fragment.setUserVisibleHint(false);
- }
-
- return fragment;
- }
-
- @Override
- public void destroyItem(ViewGroup container, int position, Object object) {
- if (mCurTransaction == null) {
- mCurTransaction = mFragmentManager.beginTransaction();
- }
- if (DEBUG) Log.v(TAG, "Detaching item #" + position + ": f=" + object
- + " v=" + ((Fragment)object).getView());
- mCurTransaction.detach((Fragment)object);
- }
-
- @Override
- public void setPrimaryItem(ViewGroup container, int position, Object object) {
- Fragment fragment = (Fragment)object;
- if (fragment != mCurrentPrimaryItem) {
- if (mCurrentPrimaryItem != null) {
- mCurrentPrimaryItem.setMenuVisibility(false);
- mCurrentPrimaryItem.setUserVisibleHint(false);
- }
- if (fragment != null) {
- fragment.setMenuVisibility(true);
- fragment.setUserVisibleHint(true);
- }
- mCurrentPrimaryItem = fragment;
- }
- }
-
- @Override
- public void finishUpdate(ViewGroup container) {
- if (mCurTransaction != null) {
- mCurTransaction.commitAllowingStateLoss();
- mCurTransaction = null;
- mFragmentManager.executePendingTransactions();
- }
- }
-
- @Override
- public boolean isViewFromObject(View view, Object object) {
- return ((Fragment)object).getView() == view;
- }
-
- @Override
- public Parcelable saveState() {
- return null;
- }
-
- @Override
- public void restoreState(Parcelable state, ClassLoader loader) {
- }
-
- public static String makeFragmentName(int viewId, int index) {
- return "android:switcher:" + viewId + ":" + index;
- }
-}
diff --git a/actionbarsherlock/library/src/android/support/v4/app/FragmentStatePagerAdapter.java b/actionbarsherlock/library/src/android/support/v4/app/FragmentStatePagerAdapter.java
deleted file mode 100644
index b82e54814..000000000
--- a/actionbarsherlock/library/src/android/support/v4/app/FragmentStatePagerAdapter.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v4.app;
-
-import java.util.ArrayList;
-
-import android.os.Bundle;
-import android.os.Parcelable;
-import android.support.v4.view.PagerAdapter;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-
-/**
- * Implementation of {@link android.support.v4.view.PagerAdapter} that
- * uses a {@link Fragment} to manage each page. This class also handles
- * saving and restoring of fragment's state.
- *
- *
This version of the pager is more useful when there are a large number
- * of pages, working more like a list view. When pages are not visible to
- * the user, their entire fragment may be destroyed, only keeping the saved
- * state of that fragment. This allows the pager to hold on to much less
- * memory associated with each visited page as compared to
- * {@link FragmentPagerAdapter} at the cost of potentially more overhead when
- * switching between pages.
- *
- *
When using FragmentPagerAdapter the host ViewPager must have a
- * valid ID set.
- *
- * Subclasses only need to implement {@link #getItem(int)}
- * and {@link #getCount()} to have a working adapter.
- *
- *
Here is an example implementation of a pager containing fragments of
- * lists:
- *
- * {@sample development/samples/Support13Demos/src/com/example/android/supportv13/app/FragmentStatePagerSupport.java
- * complete}
- *
- *
The R.layout.fragment_pager
resource of the top-level fragment is:
- *
- * {@sample development/samples/Support13Demos/res/layout/fragment_pager.xml
- * complete}
- *
- *
The R.layout.fragment_pager_list
resource containing each
- * individual fragment's layout is:
- *
- * {@sample development/samples/Support13Demos/res/layout/fragment_pager_list.xml
- * complete}
- */
-public abstract class FragmentStatePagerAdapter extends PagerAdapter {
- private static final String TAG = "FragmentStatePagerAdapter";
- private static final boolean DEBUG = false;
-
- private final FragmentManager mFragmentManager;
- private FragmentTransaction mCurTransaction = null;
-
- private ArrayList mSavedState = new ArrayList();
- private ArrayList mFragments = new ArrayList();
- private Fragment mCurrentPrimaryItem = null;
-
- public FragmentStatePagerAdapter(FragmentManager fm) {
- mFragmentManager = fm;
- }
-
- /**
- * Return the Fragment associated with a specified position.
- */
- public abstract Fragment getItem(int position);
-
- @Override
- public void startUpdate(ViewGroup container) {
- }
-
- @Override
- public Object instantiateItem(ViewGroup container, int position) {
- // If we already have this item instantiated, there is nothing
- // to do. This can happen when we are restoring the entire pager
- // from its saved state, where the fragment manager has already
- // taken care of restoring the fragments we previously had instantiated.
- if (mFragments.size() > position) {
- Fragment f = mFragments.get(position);
- if (f != null) {
- return f;
- }
- }
-
- if (mCurTransaction == null) {
- mCurTransaction = mFragmentManager.beginTransaction();
- }
-
- Fragment fragment = getItem(position);
- if (DEBUG) Log.v(TAG, "Adding item #" + position + ": f=" + fragment);
- if (mSavedState.size() > position) {
- Fragment.SavedState fss = mSavedState.get(position);
- if (fss != null) {
- fragment.setInitialSavedState(fss);
- }
- }
- while (mFragments.size() <= position) {
- mFragments.add(null);
- }
- fragment.setMenuVisibility(false);
- mFragments.set(position, fragment);
- mCurTransaction.add(container.getId(), fragment);
-
- return fragment;
- }
-
- @Override
- public void destroyItem(ViewGroup container, int position, Object object) {
- Fragment fragment = (Fragment)object;
-
- if (mCurTransaction == null) {
- mCurTransaction = mFragmentManager.beginTransaction();
- }
- if (DEBUG) Log.v(TAG, "Removing item #" + position + ": f=" + object
- + " v=" + ((Fragment)object).getView());
- while (mSavedState.size() <= position) {
- mSavedState.add(null);
- }
- mSavedState.set(position, mFragmentManager.saveFragmentInstanceState(fragment));
- mFragments.set(position, null);
-
- mCurTransaction.remove(fragment);
- }
-
- @Override
- public void setPrimaryItem(ViewGroup container, int position, Object object) {
- Fragment fragment = (Fragment)object;
- if (fragment != mCurrentPrimaryItem) {
- if (mCurrentPrimaryItem != null) {
- mCurrentPrimaryItem.setMenuVisibility(false);
- }
- if (fragment != null) {
- fragment.setMenuVisibility(true);
- }
- mCurrentPrimaryItem = fragment;
- }
- }
-
- @Override
- public void finishUpdate(ViewGroup container) {
- if (mCurTransaction != null) {
- mCurTransaction.commitAllowingStateLoss();
- mCurTransaction = null;
- mFragmentManager.executePendingTransactions();
- }
- }
-
- @Override
- public boolean isViewFromObject(View view, Object object) {
- return ((Fragment)object).getView() == view;
- }
-
- @Override
- public Parcelable saveState() {
- Bundle state = null;
- if (mSavedState.size() > 0) {
- state = new Bundle();
- Fragment.SavedState[] fss = new Fragment.SavedState[mSavedState.size()];
- mSavedState.toArray(fss);
- state.putParcelableArray("states", fss);
- }
- for (int i=0; i keys = bundle.keySet();
- for (String key: keys) {
- if (key.startsWith("f")) {
- int index = Integer.parseInt(key.substring(1));
- Fragment f = mFragmentManager.getFragment(bundle, key);
- if (f != null) {
- while (mFragments.size() <= index) {
- mFragments.add(null);
- }
- f.setMenuVisibility(false);
- mFragments.set(index, f);
- } else {
- Log.w(TAG, "Bad fragment at key " + key);
- }
- }
- }
- }
- }
-}
diff --git a/actionbarsherlock/library/src/android/support/v4/app/FragmentTransaction.java b/actionbarsherlock/library/src/android/support/v4/app/FragmentTransaction.java
deleted file mode 100644
index afc65c9d7..000000000
--- a/actionbarsherlock/library/src/android/support/v4/app/FragmentTransaction.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v4.app;
-
-/**
- * Static library support version of the framework's {@link android.app.FragmentTransaction}.
- * Used to write apps that run on platforms prior to Android 3.0. When running
- * on Android 3.0 or above, this implementation is still used; it does not try
- * to switch to the framework's implementation. See the framework SDK
- * documentation for a class overview.
- */
-public abstract class FragmentTransaction {
- /**
- * Calls {@link #add(int, Fragment, String)} with a 0 containerViewId.
- */
- public abstract FragmentTransaction add(Fragment fragment, String tag);
-
- /**
- * Calls {@link #add(int, Fragment, String)} with a null tag.
- */
- public abstract FragmentTransaction add(int containerViewId, Fragment fragment);
-
- /**
- * Add a fragment to the activity state. This fragment may optionally
- * also have its view (if {@link Fragment#onCreateView Fragment.onCreateView}
- * returns non-null) into a container view of the activity.
- *
- * @param containerViewId Optional identifier of the container this fragment is
- * to be placed in. If 0, it will not be placed in a container.
- * @param fragment The fragment to be added. This fragment must not already
- * be added to the activity.
- * @param tag Optional tag name for the fragment, to later retrieve the
- * fragment with {@link FragmentManager#findFragmentByTag(String)
- * FragmentManager.findFragmentByTag(String)}.
- *
- * @return Returns the same FragmentTransaction instance.
- */
- public abstract FragmentTransaction add(int containerViewId, Fragment fragment, String tag);
-
- /**
- * Calls {@link #replace(int, Fragment, String)} with a null tag.
- */
- public abstract FragmentTransaction replace(int containerViewId, Fragment fragment);
-
- /**
- * Replace an existing fragment that was added to a container. This is
- * essentially the same as calling {@link #remove(Fragment)} for all
- * currently added fragments that were added with the same containerViewId
- * and then {@link #add(int, Fragment, String)} with the same arguments
- * given here.
- *
- * @param containerViewId Identifier of the container whose fragment(s) are
- * to be replaced.
- * @param fragment The new fragment to place in the container.
- * @param tag Optional tag name for the fragment, to later retrieve the
- * fragment with {@link FragmentManager#findFragmentByTag(String)
- * FragmentManager.findFragmentByTag(String)}.
- *
- * @return Returns the same FragmentTransaction instance.
- */
- public abstract FragmentTransaction replace(int containerViewId, Fragment fragment, String tag);
-
- /**
- * Remove an existing fragment. If it was added to a container, its view
- * is also removed from that container.
- *
- * @param fragment The fragment to be removed.
- *
- * @return Returns the same FragmentTransaction instance.
- */
- public abstract FragmentTransaction remove(Fragment fragment);
-
- /**
- * Hides an existing fragment. This is only relevant for fragments whose
- * views have been added to a container, as this will cause the view to
- * be hidden.
- *
- * @param fragment The fragment to be hidden.
- *
- * @return Returns the same FragmentTransaction instance.
- */
- public abstract FragmentTransaction hide(Fragment fragment);
-
- /**
- * Shows a previously hidden fragment. This is only relevant for fragments whose
- * views have been added to a container, as this will cause the view to
- * be shown.
- *
- * @param fragment The fragment to be shown.
- *
- * @return Returns the same FragmentTransaction instance.
- */
- public abstract FragmentTransaction show(Fragment fragment);
-
- /**
- * Detach the given fragment from the UI. This is the same state as
- * when it is put on the back stack: the fragment is removed from
- * the UI, however its state is still being actively managed by the
- * fragment manager. When going into this state its view hierarchy
- * is destroyed.
- *
- * @param fragment The fragment to be detached.
- *
- * @return Returns the same FragmentTransaction instance.
- */
- public abstract FragmentTransaction detach(Fragment fragment);
-
- /**
- * Re-attach a fragment after it had previously been deatched from
- * the UI with {@link #detach(Fragment)}. This
- * causes its view hierarchy to be re-created, attached to the UI,
- * and displayed.
- *
- * @param fragment The fragment to be attached.
- *
- * @return Returns the same FragmentTransaction instance.
- */
- public abstract FragmentTransaction attach(Fragment fragment);
-
- /**
- * @return true
if this transaction contains no operations,
- * false
otherwise.
- */
- public abstract boolean isEmpty();
-
- /**
- * Bit mask that is set for all enter transitions.
- */
- public static final int TRANSIT_ENTER_MASK = 0x1000;
-
- /**
- * Bit mask that is set for all exit transitions.
- */
- public static final int TRANSIT_EXIT_MASK = 0x2000;
-
- /** Not set up for a transition. */
- public static final int TRANSIT_UNSET = -1;
- /** No animation for transition. */
- public static final int TRANSIT_NONE = 0;
- /** Fragment is being added onto the stack */
- public static final int TRANSIT_FRAGMENT_OPEN = 1 | TRANSIT_ENTER_MASK;
- /** Fragment is being removed from the stack */
- public static final int TRANSIT_FRAGMENT_CLOSE = 2 | TRANSIT_EXIT_MASK;
- /** Fragment should simply fade in or out; that is, no strong navigation associated
- * with it except that it is appearing or disappearing for some reason. */
- public static final int TRANSIT_FRAGMENT_FADE = 3 | TRANSIT_ENTER_MASK;
-
- /**
- * Set specific animation resources to run for the fragments that are
- * entering and exiting in this transaction. These animations will not be
- * played when popping the back stack.
- */
- public abstract FragmentTransaction setCustomAnimations(int enter, int exit);
-
- /**
- * Set specific animation resources to run for the fragments that are
- * entering and exiting in this transaction. The popEnter
- * and popExit
animations will be played for enter/exit
- * operations specifically when popping the back stack.
- */
- public abstract FragmentTransaction setCustomAnimations(int enter, int exit,
- int popEnter, int popExit);
-
- /**
- * Select a standard transition animation for this transaction. May be
- * one of {@link #TRANSIT_NONE}, {@link #TRANSIT_FRAGMENT_OPEN},
- * or {@link #TRANSIT_FRAGMENT_CLOSE}
- */
- public abstract FragmentTransaction setTransition(int transit);
-
- /**
- * Set a custom style resource that will be used for resolving transit
- * animations.
- */
- public abstract FragmentTransaction setTransitionStyle(int styleRes);
-
- /**
- * Add this transaction to the back stack. This means that the transaction
- * will be remembered after it is committed, and will reverse its operation
- * when later popped off the stack.
- *
- * @param name An optional name for this back stack state, or null.
- */
- public abstract FragmentTransaction addToBackStack(String name);
-
- /**
- * Returns true if this FragmentTransaction is allowed to be added to the back
- * stack. If this method would return false, {@link #addToBackStack(String)}
- * will throw {@link IllegalStateException}.
- *
- * @return True if {@link #addToBackStack(String)} is permitted on this transaction.
- */
- public abstract boolean isAddToBackStackAllowed();
-
- /**
- * Disallow calls to {@link #addToBackStack(String)}. Any future calls to
- * addToBackStack will throw {@link IllegalStateException}. If addToBackStack
- * has already been called, this method will throw IllegalStateException.
- */
- public abstract FragmentTransaction disallowAddToBackStack();
-
- /**
- * Set the full title to show as a bread crumb when this transaction
- * is on the back stack.
- *
- * @param res A string resource containing the title.
- */
- public abstract FragmentTransaction setBreadCrumbTitle(int res);
-
- /**
- * Like {@link #setBreadCrumbTitle(int)} but taking a raw string; this
- * method is not recommended, as the string can not be changed
- * later if the locale changes.
- */
- public abstract FragmentTransaction setBreadCrumbTitle(CharSequence text);
-
- /**
- * Set the short title to show as a bread crumb when this transaction
- * is on the back stack.
- *
- * @param res A string resource containing the title.
- */
- public abstract FragmentTransaction setBreadCrumbShortTitle(int res);
-
- /**
- * Like {@link #setBreadCrumbShortTitle(int)} but taking a raw string; this
- * method is not recommended, as the string can not be changed
- * later if the locale changes.
- */
- public abstract FragmentTransaction setBreadCrumbShortTitle(CharSequence text);
-
- /**
- * Schedules a commit of this transaction. The commit does
- * not happen immediately; it will be scheduled as work on the main thread
- * to be done the next time that thread is ready.
- *
- * A transaction can only be committed with this method
- * prior to its containing activity saving its state. If the commit is
- * attempted after that point, an exception will be thrown. This is
- * because the state after the commit can be lost if the activity needs to
- * be restored from its state. See {@link #commitAllowingStateLoss()} for
- * situations where it may be okay to lose the commit.
- *
- * @return Returns the identifier of this transaction's back stack entry,
- * if {@link #addToBackStack(String)} had been called. Otherwise, returns
- * a negative number.
- */
- public abstract int commit();
-
- /**
- * Like {@link #commit} but allows the commit to be executed after an
- * activity's state is saved. This is dangerous because the commit can
- * be lost if the activity needs to later be restored from its state, so
- * this should only be used for cases where it is okay for the UI state
- * to change unexpectedly on the user.
- */
- public abstract int commitAllowingStateLoss();
-}
diff --git a/actionbarsherlock/library/src/android/support/v4/app/HCSparseArray.java b/actionbarsherlock/library/src/android/support/v4/app/HCSparseArray.java
deleted file mode 100644
index 50161256b..000000000
--- a/actionbarsherlock/library/src/android/support/v4/app/HCSparseArray.java
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v4.app;
-
-/**
- * A copy of Honeycomb's {@link android.util.SparseArray}, that
- * provides a removeAt() method.
- */
-public class HCSparseArray {
- private static final Object DELETED = new Object();
- private boolean mGarbage = false;
-
- /**
- * Creates a new SparseArray containing no mappings.
- */
- public HCSparseArray() {
- this(10);
- }
-
- /**
- * Creates a new SparseArray containing no mappings that will not
- * require any additional memory allocation to store the specified
- * number of mappings.
- */
- public HCSparseArray(int initialCapacity) {
- initialCapacity = idealIntArraySize(initialCapacity);
-
- mKeys = new int[initialCapacity];
- mValues = new Object[initialCapacity];
- mSize = 0;
- }
-
- /**
- * Gets the Object mapped from the specified key, or null
- * if no such mapping has been made.
- */
- public E get(int key) {
- return get(key, null);
- }
-
- /**
- * Gets the Object mapped from the specified key, or the specified Object
- * if no such mapping has been made.
- */
- @SuppressWarnings("unchecked")
- public E get(int key, E valueIfKeyNotFound) {
- int i = binarySearch(mKeys, 0, mSize, key);
-
- if (i < 0 || mValues[i] == DELETED) {
- return valueIfKeyNotFound;
- } else {
- return (E) mValues[i];
- }
- }
-
- /**
- * Removes the mapping from the specified key, if there was any.
- */
- public void delete(int key) {
- int i = binarySearch(mKeys, 0, mSize, key);
-
- if (i >= 0) {
- if (mValues[i] != DELETED) {
- mValues[i] = DELETED;
- mGarbage = true;
- }
- }
- }
-
- /**
- * Alias for {@link #delete(int)}.
- */
- public void remove(int key) {
- delete(key);
- }
-
- /**
- * Removes the mapping at the specified index.
- */
- public void removeAt(int index) {
- if (mValues[index] != DELETED) {
- mValues[index] = DELETED;
- mGarbage = true;
- }
- }
-
- private void gc() {
- // Log.e("SparseArray", "gc start with " + mSize);
-
- int n = mSize;
- int o = 0;
- int[] keys = mKeys;
- Object[] values = mValues;
-
- for (int i = 0; i < n; i++) {
- Object val = values[i];
-
- if (val != DELETED) {
- if (i != o) {
- keys[o] = keys[i];
- values[o] = val;
- }
-
- o++;
- }
- }
-
- mGarbage = false;
- mSize = o;
-
- // Log.e("SparseArray", "gc end with " + mSize);
- }
-
- /**
- * Adds a mapping from the specified key to the specified value,
- * replacing the previous mapping from the specified key if there
- * was one.
- */
- public void put(int key, E value) {
- int i = binarySearch(mKeys, 0, mSize, key);
-
- if (i >= 0) {
- mValues[i] = value;
- } else {
- i = ~i;
-
- if (i < mSize && mValues[i] == DELETED) {
- mKeys[i] = key;
- mValues[i] = value;
- return;
- }
-
- if (mGarbage && mSize >= mKeys.length) {
- gc();
-
- // Search again because indices may have changed.
- i = ~binarySearch(mKeys, 0, mSize, key);
- }
-
- if (mSize >= mKeys.length) {
- int n = idealIntArraySize(mSize + 1);
-
- int[] nkeys = new int[n];
- Object[] nvalues = new Object[n];
-
- // Log.e("SparseArray", "grow " + mKeys.length + " to " + n);
- System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
- System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
-
- mKeys = nkeys;
- mValues = nvalues;
- }
-
- if (mSize - i != 0) {
- // Log.e("SparseArray", "move " + (mSize - i));
- System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
- System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
- }
-
- mKeys[i] = key;
- mValues[i] = value;
- mSize++;
- }
- }
-
- /**
- * Returns the number of key-value mappings that this SparseArray
- * currently stores.
- */
- public int size() {
- if (mGarbage) {
- gc();
- }
-
- return mSize;
- }
-
- /**
- * Given an index in the range 0...size()-1
, returns
- * the key from the index
th key-value mapping that this
- * SparseArray stores.
- */
- public int keyAt(int index) {
- if (mGarbage) {
- gc();
- }
-
- return mKeys[index];
- }
-
- /**
- * Given an index in the range 0...size()-1
, returns
- * the value from the index
th key-value mapping that this
- * SparseArray stores.
- */
- @SuppressWarnings("unchecked")
- public E valueAt(int index) {
- if (mGarbage) {
- gc();
- }
-
- return (E) mValues[index];
- }
-
- /**
- * Given an index in the range 0...size()-1
, sets a new
- * value for the index
th key-value mapping that this
- * SparseArray stores.
- */
- public void setValueAt(int index, E value) {
- if (mGarbage) {
- gc();
- }
-
- mValues[index] = value;
- }
-
- /**
- * Returns the index for which {@link #keyAt} would return the
- * specified key, or a negative number if the specified
- * key is not mapped.
- */
- public int indexOfKey(int key) {
- if (mGarbage) {
- gc();
- }
-
- return binarySearch(mKeys, 0, mSize, key);
- }
-
- /**
- * Returns an index for which {@link #valueAt} would return the
- * specified key, or a negative number if no keys map to the
- * specified value.
- * Beware that this is a linear search, unlike lookups by key,
- * and that multiple keys can map to the same value and this will
- * find only one of them.
- */
- public int indexOfValue(E value) {
- if (mGarbage) {
- gc();
- }
-
- for (int i = 0; i < mSize; i++)
- if (mValues[i] == value)
- return i;
-
- return -1;
- }
-
- /**
- * Removes all key-value mappings from this SparseArray.
- */
- public void clear() {
- int n = mSize;
- Object[] values = mValues;
-
- for (int i = 0; i < n; i++) {
- values[i] = null;
- }
-
- mSize = 0;
- mGarbage = false;
- }
-
- /**
- * Puts a key/value pair into the array, optimizing for the case where
- * the key is greater than all existing keys in the array.
- */
- public void append(int key, E value) {
- if (mSize != 0 && key <= mKeys[mSize - 1]) {
- put(key, value);
- return;
- }
-
- if (mGarbage && mSize >= mKeys.length) {
- gc();
- }
-
- int pos = mSize;
- if (pos >= mKeys.length) {
- int n = idealIntArraySize(pos + 1);
-
- int[] nkeys = new int[n];
- Object[] nvalues = new Object[n];
-
- // Log.e("SparseArray", "grow " + mKeys.length + " to " + n);
- System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
- System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
-
- mKeys = nkeys;
- mValues = nvalues;
- }
-
- mKeys[pos] = key;
- mValues[pos] = value;
- mSize = pos + 1;
- }
-
- private static int binarySearch(int[] a, int start, int len, int key) {
- int high = start + len, low = start - 1, guess;
-
- while (high - low > 1) {
- guess = (high + low) / 2;
-
- if (a[guess] < key)
- low = guess;
- else
- high = guess;
- }
-
- if (high == start + len)
- return ~(start + len);
- else if (a[high] == key)
- return high;
- else
- return ~high;
- }
-
- static int idealByteArraySize(int need) {
- for (int i = 4; i < 32; i++)
- if (need <= (1 << i) - 12)
- return (1 << i) - 12;
-
- return need;
- }
-
- static int idealIntArraySize(int need) {
- return idealByteArraySize(need * 4) / 4;
- }
-
- private int[] mKeys;
- private Object[] mValues;
- private int mSize;
-}
diff --git a/actionbarsherlock/library/src/android/support/v4/app/ListFragment.java b/actionbarsherlock/library/src/android/support/v4/app/ListFragment.java
deleted file mode 100644
index c901b7dae..000000000
--- a/actionbarsherlock/library/src/android/support/v4/app/ListFragment.java
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v4.app;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.os.Handler;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.animation.AnimationUtils;
-import android.widget.AdapterView;
-import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-import android.widget.ListAdapter;
-import android.widget.ListView;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-
-/**
- * Static library support version of the framework's {@link android.app.ListFragment}.
- * Used to write apps that run on platforms prior to Android 3.0. When running
- * on Android 3.0 or above, this implementation is still used; it does not try
- * to switch to the framework's implementation. See the framework SDK
- * documentation for a class overview.
- */
-public class ListFragment extends Fragment {
- static final int INTERNAL_EMPTY_ID = 0x00ff0001;
- static final int INTERNAL_PROGRESS_CONTAINER_ID = 0x00ff0002;
- static final int INTERNAL_LIST_CONTAINER_ID = 0x00ff0003;
-
- final private Handler mHandler = new Handler();
-
- final private Runnable mRequestFocus = new Runnable() {
- public void run() {
- mList.focusableViewAvailable(mList);
- }
- };
-
- final private AdapterView.OnItemClickListener mOnClickListener
- = new AdapterView.OnItemClickListener() {
- public void onItemClick(AdapterView> parent, View v, int position, long id) {
- onListItemClick((ListView)parent, v, position, id);
- }
- };
-
- ListAdapter mAdapter;
- ListView mList;
- View mEmptyView;
- TextView mStandardEmptyView;
- View mProgressContainer;
- View mListContainer;
- CharSequence mEmptyText;
- boolean mListShown;
-
- public ListFragment() {
- }
-
- /**
- * Provide default implementation to return a simple list view. Subclasses
- * can override to replace with their own layout. If doing so, the
- * returned view hierarchy must have a ListView whose id
- * is {@link android.R.id#list android.R.id.list} and can optionally
- * have a sibling view id {@link android.R.id#empty android.R.id.empty}
- * that is to be shown when the list is empty.
- *
- * If you are overriding this method with your own custom content,
- * consider including the standard layout {@link android.R.layout#list_content}
- * in your layout file, so that you continue to retain all of the standard
- * behavior of ListFragment. In particular, this is currently the only
- * way to have the built-in indeterminant progress state be shown.
- */
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- final Context context = getActivity();
-
- FrameLayout root = new FrameLayout(context);
-
- // ------------------------------------------------------------------
-
- LinearLayout pframe = new LinearLayout(context);
- pframe.setId(INTERNAL_PROGRESS_CONTAINER_ID);
- pframe.setOrientation(LinearLayout.VERTICAL);
- pframe.setVisibility(View.GONE);
- pframe.setGravity(Gravity.CENTER);
-
- ProgressBar progress = new ProgressBar(context, null,
- android.R.attr.progressBarStyleLarge);
- pframe.addView(progress, new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
-
- root.addView(pframe, new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
-
- // ------------------------------------------------------------------
-
- FrameLayout lframe = new FrameLayout(context);
- lframe.setId(INTERNAL_LIST_CONTAINER_ID);
-
- TextView tv = new TextView(getActivity());
- tv.setId(INTERNAL_EMPTY_ID);
- tv.setGravity(Gravity.CENTER);
- lframe.addView(tv, new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
-
- ListView lv = new ListView(getActivity());
- lv.setId(android.R.id.list);
- lv.setDrawSelectorOnTop(false);
- lframe.addView(lv, new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
-
- root.addView(lframe, new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
-
- // ------------------------------------------------------------------
-
- root.setLayoutParams(new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
-
- return root;
- }
-
- /**
- * Attach to list view once the view hierarchy has been created.
- */
- @Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- ensureList();
- }
-
- /**
- * Detach from list view.
- */
- @Override
- public void onDestroyView() {
- mHandler.removeCallbacks(mRequestFocus);
- mList = null;
- mListShown = false;
- mEmptyView = mProgressContainer = mListContainer = null;
- mStandardEmptyView = null;
- super.onDestroyView();
- }
-
- /**
- * This method will be called when an item in the list is selected.
- * Subclasses should override. Subclasses can call
- * getListView().getItemAtPosition(position) if they need to access the
- * data associated with the selected item.
- *
- * @param l The ListView where the click happened
- * @param v The view that was clicked within the ListView
- * @param position The position of the view in the list
- * @param id The row id of the item that was clicked
- */
- public void onListItemClick(ListView l, View v, int position, long id) {
- }
-
- /**
- * Provide the cursor for the list view.
- */
- public void setListAdapter(ListAdapter adapter) {
- boolean hadAdapter = mAdapter != null;
- mAdapter = adapter;
- if (mList != null) {
- mList.setAdapter(adapter);
- if (!mListShown && !hadAdapter) {
- // The list was hidden, and previously didn't have an
- // adapter. It is now time to show it.
- setListShown(true, getView().getWindowToken() != null);
- }
- }
- }
-
- /**
- * Set the currently selected list item to the specified
- * position with the adapter's data
- *
- * @param position
- */
- public void setSelection(int position) {
- ensureList();
- mList.setSelection(position);
- }
-
- /**
- * Get the position of the currently selected list item.
- */
- public int getSelectedItemPosition() {
- ensureList();
- return mList.getSelectedItemPosition();
- }
-
- /**
- * Get the cursor row ID of the currently selected list item.
- */
- public long getSelectedItemId() {
- ensureList();
- return mList.getSelectedItemId();
- }
-
- /**
- * Get the activity's list view widget.
- */
- public ListView getListView() {
- ensureList();
- return mList;
- }
-
- /**
- * The default content for a ListFragment has a TextView that can
- * be shown when the list is empty. If you would like to have it
- * shown, call this method to supply the text it should use.
- */
- public void setEmptyText(CharSequence text) {
- ensureList();
- if (mStandardEmptyView == null) {
- throw new IllegalStateException("Can't be used with a custom content view");
- }
- mStandardEmptyView.setText(text);
- if (mEmptyText == null) {
- mList.setEmptyView(mStandardEmptyView);
- }
- mEmptyText = text;
- }
-
- /**
- * Control whether the list is being displayed. You can make it not
- * displayed if you are waiting for the initial data to show in it. During
- * this time an indeterminant progress indicator will be shown instead.
- *
- *
Applications do not normally need to use this themselves. The default
- * behavior of ListFragment is to start with the list not being shown, only
- * showing it once an adapter is given with {@link #setListAdapter(ListAdapter)}.
- * If the list at that point had not been shown, when it does get shown
- * it will be do without the user ever seeing the hidden state.
- *
- * @param shown If true, the list view is shown; if false, the progress
- * indicator. The initial value is true.
- */
- public void setListShown(boolean shown) {
- setListShown(shown, true);
- }
-
- /**
- * Like {@link #setListShown(boolean)}, but no animation is used when
- * transitioning from the previous state.
- */
- public void setListShownNoAnimation(boolean shown) {
- setListShown(shown, false);
- }
-
- /**
- * Control whether the list is being displayed. You can make it not
- * displayed if you are waiting for the initial data to show in it. During
- * this time an indeterminant progress indicator will be shown instead.
- *
- * @param shown If true, the list view is shown; if false, the progress
- * indicator. The initial value is true.
- * @param animate If true, an animation will be used to transition to the
- * new state.
- */
- private void setListShown(boolean shown, boolean animate) {
- ensureList();
- if (mProgressContainer == null) {
- throw new IllegalStateException("Can't be used with a custom content view");
- }
- if (mListShown == shown) {
- return;
- }
- mListShown = shown;
- if (shown) {
- if (animate) {
- mProgressContainer.startAnimation(AnimationUtils.loadAnimation(
- getActivity(), android.R.anim.fade_out));
- mListContainer.startAnimation(AnimationUtils.loadAnimation(
- getActivity(), android.R.anim.fade_in));
- } else {
- mProgressContainer.clearAnimation();
- mListContainer.clearAnimation();
- }
- mProgressContainer.setVisibility(View.GONE);
- mListContainer.setVisibility(View.VISIBLE);
- } else {
- if (animate) {
- mProgressContainer.startAnimation(AnimationUtils.loadAnimation(
- getActivity(), android.R.anim.fade_in));
- mListContainer.startAnimation(AnimationUtils.loadAnimation(
- getActivity(), android.R.anim.fade_out));
- } else {
- mProgressContainer.clearAnimation();
- mListContainer.clearAnimation();
- }
- mProgressContainer.setVisibility(View.VISIBLE);
- mListContainer.setVisibility(View.GONE);
- }
- }
-
- /**
- * Get the ListAdapter associated with this activity's ListView.
- */
- public ListAdapter getListAdapter() {
- return mAdapter;
- }
-
- private void ensureList() {
- if (mList != null) {
- return;
- }
- View root = getView();
- if (root == null) {
- throw new IllegalStateException("Content view not yet created");
- }
- if (root instanceof ListView) {
- mList = (ListView)root;
- } else {
- mStandardEmptyView = (TextView)root.findViewById(INTERNAL_EMPTY_ID);
- if (mStandardEmptyView == null) {
- mEmptyView = root.findViewById(android.R.id.empty);
- } else {
- mStandardEmptyView.setVisibility(View.GONE);
- }
- mProgressContainer = root.findViewById(INTERNAL_PROGRESS_CONTAINER_ID);
- mListContainer = root.findViewById(INTERNAL_LIST_CONTAINER_ID);
- View rawListView = root.findViewById(android.R.id.list);
- if (!(rawListView instanceof ListView)) {
- if (rawListView == null) {
- throw new RuntimeException(
- "Your content must have a ListView whose id attribute is " +
- "'android.R.id.list'");
- }
- throw new RuntimeException(
- "Content has view with id attribute 'android.R.id.list' "
- + "that is not a ListView class");
- }
- mList = (ListView)rawListView;
- if (mEmptyView != null) {
- mList.setEmptyView(mEmptyView);
- } else if (mEmptyText != null) {
- mStandardEmptyView.setText(mEmptyText);
- mList.setEmptyView(mStandardEmptyView);
- }
- }
- mListShown = true;
- mList.setOnItemClickListener(mOnClickListener);
- if (mAdapter != null) {
- ListAdapter adapter = mAdapter;
- mAdapter = null;
- setListAdapter(adapter);
- } else {
- // We are starting without an adapter, so assume we won't
- // have our data right away and start with the progress indicator.
- if (mProgressContainer != null) {
- setListShown(false, false);
- }
- }
- mHandler.post(mRequestFocus);
- }
-}
diff --git a/actionbarsherlock/library/src/android/support/v4/app/LoaderManager.java b/actionbarsherlock/library/src/android/support/v4/app/LoaderManager.java
deleted file mode 100644
index e5b18b15d..000000000
--- a/actionbarsherlock/library/src/android/support/v4/app/LoaderManager.java
+++ /dev/null
@@ -1,827 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v4.app;
-
-import android.os.Bundle;
-import android.support.v4.content.Loader;
-import android.support.v4.util.DebugUtils;
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.lang.reflect.Modifier;
-
-/**
- * Static library support version of the framework's {@link android.app.LoaderManager}.
- * Used to write apps that run on platforms prior to Android 3.0. When running
- * on Android 3.0 or above, this implementation is still used; it does not try
- * to switch to the framework's implementation. See the framework SDK
- * documentation for a class overview.
- *
- *
Your activity must derive from {@link FragmentActivity} to use this.
- */
-public abstract class LoaderManager {
- /**
- * Callback interface for a client to interact with the manager.
- */
- public interface LoaderCallbacks {
- /**
- * Instantiate and return a new Loader for the given ID.
- *
- * @param id The ID whose loader is to be created.
- * @param args Any arguments supplied by the caller.
- * @return Return a new Loader instance that is ready to start loading.
- */
- public Loader onCreateLoader(int id, Bundle args);
-
- /**
- * Called when a previously created loader has finished its load. Note
- * that normally an application is not allowed to commit fragment
- * transactions while in this call, since it can happen after an
- * activity's state is saved. See {@link FragmentManager#beginTransaction()
- * FragmentManager.openTransaction()} for further discussion on this.
- *
- * This function is guaranteed to be called prior to the release of
- * the last data that was supplied for this Loader. At this point
- * you should remove all use of the old data (since it will be released
- * soon), but should not do your own release of the data since its Loader
- * owns it and will take care of that. The Loader will take care of
- * management of its data so you don't have to. In particular:
- *
- *
- * -
The Loader will monitor for changes to the data, and report
- * them to you through new calls here. You should not monitor the
- * data yourself. For example, if the data is a {@link android.database.Cursor}
- * and you place it in a {@link android.widget.CursorAdapter}, use
- * the {@link android.widget.CursorAdapter#CursorAdapter(android.content.Context,
- * android.database.Cursor, int)} constructor without passing
- * in either {@link android.widget.CursorAdapter#FLAG_AUTO_REQUERY}
- * or {@link android.widget.CursorAdapter#FLAG_REGISTER_CONTENT_OBSERVER}
- * (that is, use 0 for the flags argument). This prevents the CursorAdapter
- * from doing its own observing of the Cursor, which is not needed since
- * when a change happens you will get a new Cursor throw another call
- * here.
- *
- The Loader will release the data once it knows the application
- * is no longer using it. For example, if the data is
- * a {@link android.database.Cursor} from a {@link android.content.CursorLoader},
- * you should not call close() on it yourself. If the Cursor is being placed in a
- * {@link android.widget.CursorAdapter}, you should use the
- * {@link android.widget.CursorAdapter#swapCursor(android.database.Cursor)}
- * method so that the old Cursor is not closed.
- *
- *
- * @param loader The Loader that has finished.
- * @param data The data generated by the Loader.
- */
- public void onLoadFinished(Loader loader, D data);
-
- /**
- * Called when a previously created loader is being reset, and thus
- * making its data unavailable. The application should at this point
- * remove any references it has to the Loader's data.
- *
- * @param loader The Loader that is being reset.
- */
- public void onLoaderReset(Loader loader);
- }
-
- /**
- * Ensures a loader is initialized and active. If the loader doesn't
- * already exist, one is created and (if the activity/fragment is currently
- * started) starts the loader. Otherwise the last created
- * loader is re-used.
- *
- * In either case, the given callback is associated with the loader, and
- * will be called as the loader state changes. If at the point of call
- * the caller is in its started state, and the requested loader
- * already exists and has generated its data, then
- * callback {@link LoaderCallbacks#onLoadFinished} will
- * be called immediately (inside of this function), so you must be prepared
- * for this to happen.
- *
- * @param id A unique identifier for this loader. Can be whatever you want.
- * Identifiers are scoped to a particular LoaderManager instance.
- * @param args Optional arguments to supply to the loader at construction.
- * If a loader already exists (a new one does not need to be created), this
- * parameter will be ignored and the last arguments continue to be used.
- * @param callback Interface the LoaderManager will call to report about
- * changes in the state of the loader. Required.
- */
- public abstract Loader initLoader(int id, Bundle args,
- LoaderManager.LoaderCallbacks callback);
-
- /**
- * Starts a new or restarts an existing {@link android.content.Loader} in
- * this manager, registers the callbacks to it,
- * and (if the activity/fragment is currently started) starts loading it.
- * If a loader with the same id has previously been
- * started it will automatically be destroyed when the new loader completes
- * its work. The callback will be delivered before the old loader
- * is destroyed.
- *
- * @param id A unique identifier for this loader. Can be whatever you want.
- * Identifiers are scoped to a particular LoaderManager instance.
- * @param args Optional arguments to supply to the loader at construction.
- * @param callback Interface the LoaderManager will call to report about
- * changes in the state of the loader. Required.
- */
- public abstract Loader restartLoader(int id, Bundle args,
- LoaderManager.LoaderCallbacks callback);
-
- /**
- * Stops and removes the loader with the given ID. If this loader
- * had previously reported data to the client through
- * {@link LoaderCallbacks#onLoadFinished(Loader, Object)}, a call
- * will be made to {@link LoaderCallbacks#onLoaderReset(Loader)}.
- */
- public abstract void destroyLoader(int id);
-
- /**
- * Return the Loader with the given id or null if no matching Loader
- * is found.
- */
- public abstract Loader getLoader(int id);
-
- /**
- * Print the LoaderManager's state into the given stream.
- *
- * @param prefix Text to print at the front of each line.
- * @param fd The raw file descriptor that the dump is being sent to.
- * @param writer A PrintWriter to which the dump is to be set.
- * @param args Additional arguments to the dump request.
- */
- public abstract void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args);
-
- /**
- * Control whether the framework's internal loader manager debugging
- * logs are turned on. If enabled, you will see output in logcat as
- * the framework performs loader operations.
- */
- public static void enableDebugLogging(boolean enabled) {
- LoaderManagerImpl.DEBUG = enabled;
- }
-
- /**
- * Returns true if any loaders managed are currently running and have not
- * returned data to the application yet.
- */
- public boolean hasRunningLoaders() { return false; }
-}
-
-class LoaderManagerImpl extends LoaderManager {
- static final String TAG = "LoaderManager";
- static boolean DEBUG = false;
-
- // These are the currently active loaders. A loader is here
- // from the time its load is started until it has been explicitly
- // stopped or restarted by the application.
- final HCSparseArray mLoaders = new HCSparseArray();
-
- // These are previously run loaders. This list is maintained internally
- // to avoid destroying a loader while an application is still using it.
- // It allows an application to restart a loader, but continue using its
- // previously run loader until the new loader's data is available.
- final HCSparseArray mInactiveLoaders = new HCSparseArray();
-
- SupportActivity mActivity;
- boolean mStarted;
- boolean mRetaining;
- boolean mRetainingStarted;
-
- boolean mCreatingLoader;
-
- final class LoaderInfo implements Loader.OnLoadCompleteListener