From e181bd9b5e6a3e5382a1ff3c40b9ce2cb43c7971 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Tue, 25 Sep 2012 14:15:15 -0700 Subject: Fix AbsListView to correctly retain its state if not layed out. This covers a hole where if the list view restores its state and then is asked to save its state before its layout happens, the original state is lost. Instead we just store that original state. Also tweak FragmentManager to make sure an inactive fragment can not have its state moved up out of CREATED. Bug #7232088: ListView saved state being lost in some cases Change-Id: I5b40f37c259c7bcbe17dd1330016f9531f1b5534 --- core/java/android/app/FragmentManager.java | 2 +- core/java/android/widget/AbsListView.java | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) (limited to 'core/java') diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java index 7f11437..aad5487 100644 --- a/core/java/android/app/FragmentManager.java +++ b/core/java/android/app/FragmentManager.java @@ -776,7 +776,7 @@ final class FragmentManagerImpl extends FragmentManager { // + " mRemoving=" + f.mRemoving + " Callers=" + Debug.getCallers(5)); // Fragments that are not currently added will sit in the onCreate() state. - if (!f.mAdded && newState > Fragment.CREATED) { + if ((!f.mAdded || f.mDetached) && newState > Fragment.CREATED) { newState = Fragment.CREATED; } if (f.mRemoving && newState > f.mState) { diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 920d44f..6264315 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -675,6 +675,14 @@ public abstract class AbsListView extends AdapterView implements Te static final Interpolator sLinearInterpolator = new LinearInterpolator(); /** + * The saved state that we will be restoring from when we next sync. + * Kept here so that if we happen to be asked to save our state before + * the sync happens, we can return this existing data rather than losing + * it. + */ + private SavedState mPendingSync; + + /** * Interface definition for a callback to be invoked when the list or grid * has been scrolled. */ @@ -1612,6 +1620,21 @@ public abstract class AbsListView extends AdapterView implements Te SavedState ss = new SavedState(superState); + if (mPendingSync != null) { + // Just keep what we last restored. + ss.selectedId = mPendingSync.selectedId; + ss.firstId = mPendingSync.firstId; + ss.viewTop = mPendingSync.viewTop; + ss.position = mPendingSync.position; + ss.height = mPendingSync.height; + ss.filter = mPendingSync.filter; + ss.inActionMode = mPendingSync.inActionMode; + ss.checkedItemCount = mPendingSync.checkedItemCount; + ss.checkState = mPendingSync.checkState; + ss.checkIdState = mPendingSync.checkIdState; + return ss; + } + boolean haveChildren = getChildCount() > 0 && mItemCount > 0; long selectedId = getSelectedItemId(); ss.selectedId = selectedId; @@ -1692,6 +1715,7 @@ public abstract class AbsListView extends AdapterView implements Te if (ss.selectedId >= 0) { mNeedSync = true; + mPendingSync = ss; mSyncRowId = ss.selectedId; mSyncPosition = ss.position; mSpecificTop = ss.viewTop; @@ -1702,6 +1726,7 @@ public abstract class AbsListView extends AdapterView implements Te setNextSelectedPositionInt(INVALID_POSITION); mSelectorPosition = INVALID_POSITION; mNeedSync = true; + mPendingSync = ss; mSyncRowId = ss.firstId; mSyncPosition = ss.position; mSpecificTop = ss.viewTop; @@ -1803,6 +1828,7 @@ public abstract class AbsListView extends AdapterView implements Te mDataChanged = false; mPositionScrollAfterLayout = null; mNeedSync = false; + mPendingSync = null; mOldSelectedPosition = INVALID_POSITION; mOldSelectedRowId = INVALID_ROW_ID; setSelectedPositionInt(INVALID_POSITION); @@ -5209,6 +5235,7 @@ public abstract class AbsListView extends AdapterView implements Te if (mNeedSync) { // Update this first, since setNextSelectedPositionInt inspects it mNeedSync = false; + mPendingSync = null; if (mTranscriptMode == TRANSCRIPT_MODE_ALWAYS_SCROLL) { mLayoutMode = LAYOUT_FORCE_BOTTOM; @@ -5324,6 +5351,7 @@ public abstract class AbsListView extends AdapterView implements Te mNextSelectedPosition = INVALID_POSITION; mNextSelectedRowId = INVALID_ROW_ID; mNeedSync = false; + mPendingSync = null; mSelectorPosition = INVALID_POSITION; checkSelectionChanged(); } -- cgit v1.1