Merge "Change the "start deferred" fragment API to "user visible hint"" into ics-mr1

This commit is contained in:
Adam Powell
2011-11-07 14:56:36 -08:00
committed by Android (Google) Code Review
3 changed files with 60 additions and 21 deletions

View File

@@ -3235,6 +3235,7 @@ package android.app {
method public final android.app.Fragment getTargetFragment();
method public final int getTargetRequestCode();
method public final java.lang.CharSequence getText(int);
method public boolean getUserVisibleHint();
method public android.view.View getView();
method public final int hashCode();
method public static android.app.Fragment instantiate(android.content.Context, java.lang.String);
@@ -3245,7 +3246,6 @@ package android.app {
method public final boolean isInLayout();
method public final boolean isRemoving();
method public final boolean isResumed();
method public boolean isStartDeferred();
method public final boolean isVisible();
method public void onActivityCreated(android.os.Bundle);
method public void onActivityResult(int, int, android.content.Intent);
@@ -3281,8 +3281,8 @@ package android.app {
method public void setInitialSavedState(android.app.Fragment.SavedState);
method public void setMenuVisibility(boolean);
method public void setRetainInstance(boolean);
method public void setStartDeferred(boolean);
method public void setTargetFragment(android.app.Fragment, int);
method public void setUserVisibleHint(boolean);
method public void startActivity(android.content.Intent);
method public void startActivityForResult(android.content.Intent, int);
method public void unregisterForContextMenu(android.view.View);

View File

@@ -458,6 +458,9 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
// have been started and their loaders are finished.
boolean mDeferStart;
// Hint provided by the app that this fragment is currently visible to the user.
boolean mUserVisibleHint = true;
LoaderManagerImpl mLoaderManager;
boolean mLoadersStarted;
boolean mCheckedForLoaderManager;
@@ -915,31 +918,32 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
}
/**
* Set whether this fragment should enter the started state as normal or if
* start should be deferred until a system-determined convenient time, such
* as after any loaders have completed their work.
* Set a hint to the system about whether this fragment's UI is currently visible
* to the user. This hint defaults to true and is persistent across fragment instance
* state save and restore.
*
* <p>This option is not sticky across fragment starts; after a deferred start
* completes this option will be set to false.</p>
* <p>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.</p>
*
* @param deferResume true if this fragment can defer its resume until after others
* @param isVisibleToUser true if this fragment's UI is currently visible to the user (default),
* false if it is not.
*/
public void setStartDeferred(boolean deferResume) {
if (mDeferStart && !deferResume) {
public void setUserVisibleHint(boolean isVisibleToUser) {
if (!mUserVisibleHint && isVisibleToUser && mState < STARTED) {
mFragmentManager.performPendingDeferredStart(this);
}
mDeferStart = deferResume;
mUserVisibleHint = isVisibleToUser;
mDeferStart = !isVisibleToUser;
}
/**
* Returns true if this fragment's move to the started state has been deferred.
* If this returns true it will be started once other fragments' loaders
* have finished running.
*
* @return true if this fragment's start has been deferred.
* @return The current value of the user-visible hint on this fragment.
* @see #setUserVisibleHint(boolean)
*/
public boolean isStartDeferred() {
return mDeferStart;
public boolean getUserVisibleHint() {
return mUserVisibleHint;
}
/**
@@ -1477,7 +1481,8 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
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.println(mRetaining);
writer.print(" mRetaining="); writer.print(mRetaining);
writer.print(" mUserVisibleHint="); writer.println(mUserVisibleHint);
if (mFragmentManager != null) {
writer.print(prefix); writer.print("mFragmentManager=");
writer.println(mFragmentManager);

View File

@@ -382,6 +382,7 @@ final class FragmentManagerImpl extends FragmentManager {
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<Runnable> mPendingActions;
Runnable[] mTmpActions;
@@ -406,6 +407,7 @@ final class FragmentManagerImpl extends FragmentManager {
boolean mStateSaved;
boolean mDestroyed;
String mNoTransactionsBecause;
boolean mHavePendingDeferredStart;
// Temporary vars for state save and restore.
Bundle mStateBundle = null;
@@ -711,6 +713,11 @@ final class FragmentManagerImpl extends FragmentManager {
public void performPendingDeferredStart(Fragment f) {
if (f.mDeferStart) {
if (mExecutingActions) {
// Wait until we're done executing our pending transactions
mHavePendingDeferredStart = true;
return;
}
f.mDeferStart = false;
moveToState(f, mCurState, 0, 0);
}
@@ -757,6 +764,14 @@ final class FragmentManagerImpl extends FragmentManager {
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.mFragments;
@@ -1343,7 +1358,7 @@ final class FragmentManagerImpl extends FragmentManager {
synchronized (this) {
if (mPendingActions == null || mPendingActions.size() == 0) {
return didSomething;
break;
}
numActions = mPendingActions.size();
@@ -1363,8 +1378,23 @@ final class FragmentManagerImpl extends FragmentManager {
mExecutingActions = false;
didSomething = true;
}
if (mHavePendingDeferredStart) {
boolean loadersRunning = false;
for (int i=0; i<mActive.size(); i++) {
Fragment f = mActive.get(i);
if (f != null && f.mLoaderManager != null) {
loadersRunning |= f.mLoaderManager.hasRunningLoaders();
}
}
if (!loadersRunning) {
mHavePendingDeferredStart = false;
startPendingDeferredFragments();
}
}
return didSomething;
}
void reportBackStackChanged() {
if (mBackStackChangeListeners != null) {
for (int i=0; i<mBackStackChangeListeners.size(); i++) {
@@ -1500,6 +1530,10 @@ final class FragmentManagerImpl extends FragmentManager {
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;
}