From 31fdccccb341c071ca5c9cc558e18f2446c80ea8 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 12 Sep 2016 21:18:56 +0200 Subject: remember scroll position on rotate. fixes #2011 --- .../pixart/messenger/ui/ConversationActivity.java | 37 +++++++++++++++----- .../pixart/messenger/ui/ConversationFragment.java | 39 +++++++++++++++++++--- 2 files changed, 62 insertions(+), 14 deletions(-) (limited to 'src/main') diff --git a/src/main/java/de/pixart/messenger/ui/ConversationActivity.java b/src/main/java/de/pixart/messenger/ui/ConversationActivity.java index 8e596303b..6d03cb5d6 100644 --- a/src/main/java/de/pixart/messenger/ui/ConversationActivity.java +++ b/src/main/java/de/pixart/messenger/ui/ConversationActivity.java @@ -110,12 +110,15 @@ public class ConversationActivity extends XmppActivity private static final String STATE_OPEN_CONVERSATION = "state_open_conversation"; private static final String STATE_PANEL_OPEN = "state_panel_open"; private static final String STATE_PENDING_URI = "state_pending_uri"; + private static final String STATE_FIRST_VISIBLE = "first_visible"; + private static final String STATE_OFFSET_FROM_TOP = "offset_from_top"; final private List mPendingImageUris = new ArrayList<>(); final private List mPendingPhotoUris = new ArrayList<>(); final private List mPendingFileUris = new ArrayList<>(); final private List mPendingVideoUris = new ArrayList<>(); - private String mOpenConverstaion = null; + private String mOpenConversation = null; private boolean mPanelOpen = true; + private Pair mScrollPosition = null; private Uri mPendingGeoUri = null; private boolean forbidProcessingPendings = false; private Message mPendingDownloadableMessage = null; @@ -191,9 +194,17 @@ public class ConversationActivity extends XmppActivity protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState != null) { - mOpenConverstaion = savedInstanceState.getString(STATE_OPEN_CONVERSATION, null); + mOpenConversation = savedInstanceState.getString(STATE_OPEN_CONVERSATION, null); mPanelOpen = savedInstanceState.getBoolean(STATE_PANEL_OPEN, true); - String pending = savedInstanceState.getString(STATE_PENDING_URI, null); + int pos = savedInstanceState.getInt(STATE_FIRST_VISIBLE, -1); + int offset = savedInstanceState.getInt(STATE_OFFSET_FROM_TOP, 1); + if (pos >= 0 && offset <= 0) { + Log.d(Config.LOGTAG, "retrieved scroll position from instanceState " + pos + ":" + offset); + mScrollPosition = new Pair<>(pos, offset); + } else { + mScrollPosition = null; + } + String pending = savedInstanceState.getString(STATE_PENDING_URI, null); if (pending != null) { mPendingImageUris.clear(); mPendingImageUris.add(Uri.parse(pending)); @@ -1274,7 +1285,7 @@ public class ConversationActivity extends XmppActivity @Override protected void onNewIntent(final Intent intent) { if (intent != null && ACTION_VIEW_CONVERSATION.equals(intent.getAction())) { - mOpenConverstaion = null; + mOpenConversation = null; if (xmppConnectionServiceBound) { handleViewConversationIntent(intent); intent.setAction(Intent.ACTION_MAIN); @@ -1323,7 +1334,12 @@ public class ConversationActivity extends XmppActivity Conversation conversation = getSelectedConversation(); if (conversation != null) { savedInstanceState.putString(STATE_OPEN_CONVERSATION, conversation.getUuid()); - } else { + Pair scrollPosition = mConversationFragment.getScrollPosition(); + if (scrollPosition != null) { + savedInstanceState.putInt(STATE_FIRST_VISIBLE, scrollPosition.first); + savedInstanceState.putInt(STATE_OFFSET_FROM_TOP, scrollPosition.second); + } + } else { savedInstanceState.remove(STATE_OPEN_CONVERSATION); } savedInstanceState.putBoolean(STATE_PANEL_OPEN, isConversationsOverviewVisable()); @@ -1411,7 +1427,7 @@ public class ConversationActivity extends XmppActivity } finish(); } - } else if (selectConversationByUuid(mOpenConverstaion)) { + } else if (selectConversationByUuid(mOpenConversation)) { if (mPanelOpen) { showConversationsOverview(); } else { @@ -1420,9 +1436,12 @@ public class ConversationActivity extends XmppActivity updateActionBarTitle(true); } } - this.mConversationFragment.reInit(getSelectedConversation()); - mOpenConverstaion = null; - } else if (intent != null && ACTION_VIEW_CONVERSATION.equals(intent.getAction())) { + if (this.mConversationFragment.reInit(getSelectedConversation())) { + Log.d(Config.LOGTAG, "setting scroll position on fragment"); + this.mConversationFragment.setScrollPosition(mScrollPosition); + } + mOpenConversation = null; + } else if (intent != null && ACTION_VIEW_CONVERSATION.equals(intent.getAction())) { clearPending(); handleViewConversationIntent(intent); intent.setAction(Intent.ACTION_MAIN); diff --git a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java index 736c07aa9..1c9e215af 100644 --- a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java +++ b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java @@ -12,6 +12,8 @@ import android.content.IntentSender.SendIntentException; import android.os.Bundle; import android.os.Handler; import android.text.InputType; +import android.util.Log; +import android.util.Pair; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.Gravity; @@ -153,8 +155,12 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa View v = messagesView.getChildAt(0); final int pxOffset = (v == null) ? 0 : v.getTop(); ConversationFragment.this.conversation.populateWithMessages(ConversationFragment.this.messageList); - updateStatusMessages(); - messageListAdapter.notifyDataSetChanged(); + try { + updateStatusMessages(); + } catch (IllegalStateException e) { + Log.d(Config.LOGTAG, "caught illegal state exception while updating status messages"); + } + messageListAdapter.notifyDataSetChanged(); int pos = Math.max(getIndexOf(uuid,messageList),0); messagesView.setSelectionFromTop(pos, pxOffset); messagesLoaded = true; @@ -210,7 +216,29 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } return -1; } - protected OnClickListener clickToDecryptListener = new OnClickListener() { + + public Pair getScrollPosition() { + if (this.messagesView.getCount() == 0 || + this.messagesView.getLastVisiblePosition() == this.messagesView.getCount() - 1) { + return null; + } else { + final int pos = messagesView.getFirstVisiblePosition(); + final View view = messagesView.getChildAt(0); + if (view == null) { + return null; + } else { + return new Pair<>(pos, view.getTop()); + } + } + } + + public void setScrollPosition(Pair scrollPosition) { + if (scrollPosition != null) { + this.messagesView.setSelectionFromTop(scrollPosition.first, scrollPosition.second); + } + } + + protected OnClickListener clickToDecryptListener = new OnClickListener() { @Override public void onClick(View v) { @@ -747,9 +775,9 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } } - public void reInit(Conversation conversation) { + public boolean reInit(Conversation conversation) { if (conversation == null) { - return; + return false; } this.activity = (ConversationActivity) getActivity(); setupIme(); @@ -785,6 +813,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa pos = i < 0 ? bottom : i; } messagesView.setSelection(pos); + return pos == bottom; } } -- cgit v1.2.3