am 2551bcfb: Merge "Remember our scroll position when we return to conv list" into jb-ub-mail-ur10
* commit '2551bcfb449a902a99a593390e90598d6e5f9fbc':
Remember our scroll position when we return to conv list
diff --git a/src/com/android/mail/ui/AbstractActivityController.java b/src/com/android/mail/ui/AbstractActivityController.java
index fe38134..f2c28d8 100644
--- a/src/com/android/mail/ui/AbstractActivityController.java
+++ b/src/com/android/mail/ui/AbstractActivityController.java
@@ -45,6 +45,7 @@
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
+import android.os.Parcelable;
import android.provider.SearchRecentSuggestions;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
@@ -158,7 +159,10 @@
/** Tag for {@link #mDetachedConvUri} */
private static final String SAVED_DETACHED_CONV_URI = "saved-detached-conv-uri";
/** Key to store {@link #mInbox}. */
- private final static String SAVED_INBOX_KEY = "m-inbox";
+ private static final String SAVED_INBOX_KEY = "m-inbox";
+ /** Key to store {@link #mConversationListScrollPositions} */
+ private static final String SAVED_CONVERSATION_LIST_SCROLL_POSITIONS =
+ "saved-conversation-list-scroll-positions";
/** Tag used when loading a wait fragment */
protected static final String TAG_WAIT = "wait-fragment";
@@ -189,6 +193,9 @@
*/
private Uri mDetachedConvUri;
+ /** A map of {@link Folder} {@link Uri} to scroll position in the conversation list. */
+ private final Bundle mConversationListScrollPositions = new Bundle();
+
/** A {@link android.content.BroadcastReceiver} that suppresses new e-mail notifications. */
private SuppressNotificationReceiver mNewEmailReceiver = null;
@@ -2043,6 +2050,9 @@
mSafeToModifyFragments = false;
outState.putParcelable(SAVED_INBOX_KEY, mInbox);
+
+ outState.putBundle(SAVED_CONVERSATION_LIST_SCROLL_POSITIONS,
+ mConversationListScrollPositions);
}
/**
@@ -2260,6 +2270,10 @@
}
mInbox = savedState.getParcelable(SAVED_INBOX_KEY);
+
+ mConversationListScrollPositions.clear();
+ mConversationListScrollPositions.putAll(
+ savedState.getBundle(SAVED_CONVERSATION_LIST_SCROLL_POSITIONS));
}
/**
@@ -4311,4 +4325,15 @@
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
}
+
+ @Override
+ public Parcelable getConversationListScrollPosition(final String folderUri) {
+ return mConversationListScrollPositions.getParcelable(folderUri);
+ }
+
+ @Override
+ public void setConversationListScrollPosition(final String folderUri,
+ final Parcelable savedPosition) {
+ mConversationListScrollPositions.putParcelable(folderUri, savedPosition);
+ }
}
diff --git a/src/com/android/mail/ui/AnimatedAdapter.java b/src/com/android/mail/ui/AnimatedAdapter.java
index a3b65ea..fad7b3a 100644
--- a/src/com/android/mail/ui/AnimatedAdapter.java
+++ b/src/com/android/mail/ui/AnimatedAdapter.java
@@ -730,10 +730,16 @@
@Override
public long getItemId(int position) {
- if (mShowFooter && position == getCount() - 1
- || mSpecialViews.get(position) != null) {
+ if (mShowFooter && position == getCount() - 1) {
return -1;
}
+
+ final ConversationSpecialItemView specialView = mSpecialViews.get(position);
+ if (specialView != null) {
+ // TODO(skennedy) We probably want something better than this
+ return specialView.hashCode();
+ }
+
final int cursorPos = position - getPositionOffset(position);
// advance the cursor to the right position and read the cached conversation, if present
//
diff --git a/src/com/android/mail/ui/ConversationListCallbacks.java b/src/com/android/mail/ui/ConversationListCallbacks.java
index ff3f83c..23f2873 100644
--- a/src/com/android/mail/ui/ConversationListCallbacks.java
+++ b/src/com/android/mail/ui/ConversationListCallbacks.java
@@ -19,6 +19,8 @@
import android.app.LoaderManager.LoaderCallbacks;
import android.database.DataSetObserver;
+import android.os.Bundle;
+import android.os.Parcelable;
import com.android.mail.browse.ConversationCursor;
import com.android.mail.providers.Conversation;
@@ -80,7 +82,7 @@
void commitDestructiveActions(boolean animate);
/**
- * Detect if there are any animations occuring in the conversation list.
+ * Detect if there are any animations occurring in the conversation list.
*/
boolean isAnimating();
@@ -88,4 +90,26 @@
* Tell the controller that the conversation view has entered detached mode.
*/
void setDetachedMode();
+
+ String CONVERSATION_LIST_SCROLL_POSITION_INDEX = "index";
+ String CONVERSATION_LIST_SCROLL_POSITION_OFFSET = "offset";
+
+ /**
+ * Gets the last save scroll position of the conversation list for the specified Folder.
+ *
+ * @return A {@link Bundle} containing two ints,
+ * {@link #CONVERSATION_LIST_SCROLL_POSITION_INDEX} and
+ * {@link #CONVERSATION_LIST_SCROLL_POSITION_OFFSET}, or <code>null</code>
+ */
+ Parcelable getConversationListScrollPosition(String folderUri);
+
+ /**
+ * Sets the last save scroll position of the conversation list for the specified Folder for
+ * restoration on returning to this list.
+ *
+ * @param savedPosition A {@link Bundle} containing two ints,
+ * {@link #CONVERSATION_LIST_SCROLL_POSITION_INDEX} and
+ * {@link #CONVERSATION_LIST_SCROLL_POSITION_OFFSET}
+ */
+ void setConversationListScrollPosition(String folderUri, Parcelable savedPosition);
}
diff --git a/src/com/android/mail/ui/ConversationListFragment.java b/src/com/android/mail/ui/ConversationListFragment.java
index 4d8ecad..32b8b3d 100644
--- a/src/com/android/mail/ui/ConversationListFragment.java
+++ b/src/com/android/mail/ui/ConversationListFragment.java
@@ -27,6 +27,7 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
+import android.os.Parcelable;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
@@ -155,6 +156,12 @@
private long mSelectionModeExitedTimestamp = -1;
/**
+ * If <code>true</code>, we have restored (or attempted to restore) the list's scroll position
+ * from when we were last on this conversation list.
+ */
+ private boolean mScrollPositionRestored = false;
+
+ /**
* If the current list is for a folder with children, this set of loader callbacks will
* create a loader for all the child folders, and will return an {@link ObjectCursor} over the
* list.
@@ -628,6 +635,8 @@
final ConversationCursor conversationCursor = getConversationListCursor();
if (conversationCursor != null) {
conversationCursor.handleNotificationActions();
+
+ restoreLastScrolledPosition();
}
mSelectedSet.addObserver(mConversationSetObserver);
@@ -638,6 +647,8 @@
super.onPause();
mSelectedSet.removeObserver(mConversationSetObserver);
+
+ saveLastScrolledPosition();
}
@Override
@@ -939,6 +950,12 @@
// Check against the previous cursor here and see if they are the same. If they are, then
// do a notifyDataSetChanged.
final ConversationCursor newCursor = mCallbacks.getConversationListCursor();
+
+ if (newCursor == null && mListAdapter.getCursor() != null) {
+ // We're losing our cursor, so save our scroll position
+ saveLastScrolledPosition();
+ }
+
mListAdapter.swapCursor(newCursor);
// When the conversation cursor is *updated*, we get back the same instance. In that
// situation, CursorAdapter.swapCursor() silently returns, without forcing a
@@ -952,17 +969,17 @@
if (newCursor != null && newCursor.getCount() > 0) {
newCursor.markContentsSeen();
+ restoreLastScrolledPosition();
}
// If a current conversation is available, and none is selected in the list, then ask
// the list to select the current conversation.
final Conversation conv = mCallbacks.getCurrentConversation();
- if (conv == null) {
- return;
- }
- if (mListView.getChoiceMode() != ListView.CHOICE_MODE_NONE
- && mListView.getCheckedItemPosition() == -1) {
- setSelected(conv.position, true);
+ if (conv != null) {
+ if (mListView.getChoiceMode() != ListView.CHOICE_MODE_NONE
+ && mListView.getCheckedItemPosition() == -1) {
+ setSelected(conv.position, true);
+ }
}
}
@@ -1020,4 +1037,28 @@
// Do nothing
}
};
+
+ private void saveLastScrolledPosition() {
+ if (mListAdapter.getCursor() == null) {
+ // If you save your scroll position in an empty list, you're gonna have a bad time
+ return;
+ }
+
+ final Parcelable savedState = mListView.onSaveInstanceState();
+
+ mActivity.getListHandler().setConversationListScrollPosition(
+ mFolder.conversationListUri.toString(), savedState);
+ }
+
+ private void restoreLastScrolledPosition() {
+ // Scroll to our previous position, if necessary
+ if (!mScrollPositionRestored) {
+ final Parcelable savedState = mActivity.getListHandler()
+ .getConversationListScrollPosition(mFolder.conversationListUri.toString());
+ if (savedState != null) {
+ mListView.onRestoreInstanceState(savedState);
+ }
+ mScrollPositionRestored = true;
+ }
+ }
}