Skip to content

Commit b1dbf8e

Browse files
adampAndroid (Google) Code Review
authored andcommitted
Merge "Change the "start deferred" fragment API to "user visible hint"" into ics-mr1
2 parents e1aacdf + 78fed9b commit b1dbf8e

File tree

3 files changed

+60
-21
lines changed

3 files changed

+60
-21
lines changed

api/current.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3235,6 +3235,7 @@ package android.app {
32353235
method public final android.app.Fragment getTargetFragment();
32363236
method public final int getTargetRequestCode();
32373237
method public final java.lang.CharSequence getText(int);
3238+
method public boolean getUserVisibleHint();
32383239
method public android.view.View getView();
32393240
method public final int hashCode();
32403241
method public static android.app.Fragment instantiate(android.content.Context, java.lang.String);
@@ -3245,7 +3246,6 @@ package android.app {
32453246
method public final boolean isInLayout();
32463247
method public final boolean isRemoving();
32473248
method public final boolean isResumed();
3248-
method public boolean isStartDeferred();
32493249
method public final boolean isVisible();
32503250
method public void onActivityCreated(android.os.Bundle);
32513251
method public void onActivityResult(int, int, android.content.Intent);
@@ -3281,8 +3281,8 @@ package android.app {
32813281
method public void setInitialSavedState(android.app.Fragment.SavedState);
32823282
method public void setMenuVisibility(boolean);
32833283
method public void setRetainInstance(boolean);
3284-
method public void setStartDeferred(boolean);
32853284
method public void setTargetFragment(android.app.Fragment, int);
3285+
method public void setUserVisibleHint(boolean);
32863286
method public void startActivity(android.content.Intent);
32873287
method public void startActivityForResult(android.content.Intent, int);
32883288
method public void unregisterForContextMenu(android.view.View);

core/java/android/app/Fragment.java

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,9 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
458458
// have been started and their loaders are finished.
459459
boolean mDeferStart;
460460

461+
// Hint provided by the app that this fragment is currently visible to the user.
462+
boolean mUserVisibleHint = true;
463+
461464
LoaderManagerImpl mLoaderManager;
462465
boolean mLoadersStarted;
463466
boolean mCheckedForLoaderManager;
@@ -915,31 +918,32 @@ public void setMenuVisibility(boolean menuVisible) {
915918
}
916919

917920
/**
918-
* Set whether this fragment should enter the started state as normal or if
919-
* start should be deferred until a system-determined convenient time, such
920-
* as after any loaders have completed their work.
921+
* Set a hint to the system about whether this fragment's UI is currently visible
922+
* to the user. This hint defaults to true and is persistent across fragment instance
923+
* state save and restore.
921924
*
922-
* <p>This option is not sticky across fragment starts; after a deferred start
923-
* completes this option will be set to false.</p>
925+
* <p>An app may set this to false to indicate that the fragment's UI is
926+
* scrolled out of visibility or is otherwise not directly visible to the user.
927+
* This may be used by the system to prioritize operations such as fragment lifecycle updates
928+
* or loader ordering behavior.</p>
924929
*
925-
* @param deferResume true if this fragment can defer its resume until after others
930+
* @param isVisibleToUser true if this fragment's UI is currently visible to the user (default),
931+
* false if it is not.
926932
*/
927-
public void setStartDeferred(boolean deferResume) {
928-
if (mDeferStart && !deferResume) {
933+
public void setUserVisibleHint(boolean isVisibleToUser) {
934+
if (!mUserVisibleHint && isVisibleToUser && mState < STARTED) {
929935
mFragmentManager.performPendingDeferredStart(this);
930936
}
931-
mDeferStart = deferResume;
937+
mUserVisibleHint = isVisibleToUser;
938+
mDeferStart = !isVisibleToUser;
932939
}
933940

934941
/**
935-
* Returns true if this fragment's move to the started state has been deferred.
936-
* If this returns true it will be started once other fragments' loaders
937-
* have finished running.
938-
*
939-
* @return true if this fragment's start has been deferred.
942+
* @return The current value of the user-visible hint on this fragment.
943+
* @see #setUserVisibleHint(boolean)
940944
*/
941-
public boolean isStartDeferred() {
942-
return mDeferStart;
945+
public boolean getUserVisibleHint() {
946+
return mUserVisibleHint;
943947
}
944948

945949
/**
@@ -1477,7 +1481,8 @@ public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[]
14771481
writer.print(" mMenuVisible="); writer.print(mMenuVisible);
14781482
writer.print(" mHasMenu="); writer.println(mHasMenu);
14791483
writer.print(prefix); writer.print("mRetainInstance="); writer.print(mRetainInstance);
1480-
writer.print(" mRetaining="); writer.println(mRetaining);
1484+
writer.print(" mRetaining="); writer.print(mRetaining);
1485+
writer.print(" mUserVisibleHint="); writer.println(mUserVisibleHint);
14811486
if (mFragmentManager != null) {
14821487
writer.print(prefix); writer.print("mFragmentManager=");
14831488
writer.println(mFragmentManager);

core/java/android/app/FragmentManager.java

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ final class FragmentManagerImpl extends FragmentManager {
382382
static final String TARGET_REQUEST_CODE_STATE_TAG = "android:target_req_state";
383383
static final String TARGET_STATE_TAG = "android:target_state";
384384
static final String VIEW_STATE_TAG = "android:view_state";
385+
static final String USER_VISIBLE_HINT_TAG = "android:user_visible_hint";
385386

386387
ArrayList<Runnable> mPendingActions;
387388
Runnable[] mTmpActions;
@@ -406,6 +407,7 @@ final class FragmentManagerImpl extends FragmentManager {
406407
boolean mStateSaved;
407408
boolean mDestroyed;
408409
String mNoTransactionsBecause;
410+
boolean mHavePendingDeferredStart;
409411

410412
// Temporary vars for state save and restore.
411413
Bundle mStateBundle = null;
@@ -711,6 +713,11 @@ Animator loadAnimator(Fragment fragment, int transit, boolean enter,
711713

712714
public void performPendingDeferredStart(Fragment f) {
713715
if (f.mDeferStart) {
716+
if (mExecutingActions) {
717+
// Wait until we're done executing our pending transactions
718+
mHavePendingDeferredStart = true;
719+
return;
720+
}
714721
f.mDeferStart = false;
715722
moveToState(f, mCurState, 0, 0);
716723
}
@@ -757,6 +764,14 @@ void moveToState(Fragment f, int newState, int transit, int transitionStyle) {
757764
f.mTargetRequestCode = f.mSavedFragmentState.getInt(
758765
FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0);
759766
}
767+
f.mUserVisibleHint = f.mSavedFragmentState.getBoolean(
768+
FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true);
769+
if (!f.mUserVisibleHint) {
770+
f.mDeferStart = true;
771+
if (newState > Fragment.STOPPED) {
772+
newState = Fragment.STOPPED;
773+
}
774+
}
760775
}
761776
f.mActivity = mActivity;
762777
f.mFragmentManager = mActivity.mFragments;
@@ -1343,7 +1358,7 @@ public boolean execPendingActions() {
13431358

13441359
synchronized (this) {
13451360
if (mPendingActions == null || mPendingActions.size() == 0) {
1346-
return didSomething;
1361+
break;
13471362
}
13481363

13491364
numActions = mPendingActions.size();
@@ -1363,8 +1378,23 @@ public boolean execPendingActions() {
13631378
mExecutingActions = false;
13641379
didSomething = true;
13651380
}
1381+
1382+
if (mHavePendingDeferredStart) {
1383+
boolean loadersRunning = false;
1384+
for (int i=0; i<mActive.size(); i++) {
1385+
Fragment f = mActive.get(i);
1386+
if (f != null && f.mLoaderManager != null) {
1387+
loadersRunning |= f.mLoaderManager.hasRunningLoaders();
1388+
}
1389+
}
1390+
if (!loadersRunning) {
1391+
mHavePendingDeferredStart = false;
1392+
startPendingDeferredFragments();
1393+
}
1394+
}
1395+
return didSomething;
13661396
}
1367-
1397+
13681398
void reportBackStackChanged() {
13691399
if (mBackStackChangeListeners != null) {
13701400
for (int i=0; i<mBackStackChangeListeners.size(); i++) {
@@ -1500,6 +1530,10 @@ Bundle saveFragmentBasicState(Fragment f) {
15001530
result.putSparseParcelableArray(
15011531
FragmentManagerImpl.VIEW_STATE_TAG, f.mSavedViewState);
15021532
}
1533+
if (!f.mUserVisibleHint) {
1534+
// Only add this if it's not the default value
1535+
result.putBoolean(FragmentManagerImpl.USER_VISIBLE_HINT_TAG, f.mUserVisibleHint);
1536+
}
15031537

15041538
return result;
15051539
}

0 commit comments

Comments
 (0)