diff --git a/res/drawable-hdpi/ic_scroll_down.png b/res/drawable-hdpi/ic_scroll_down.png
new file mode 100644
index 000000000..5d23096c4
Binary files /dev/null and b/res/drawable-hdpi/ic_scroll_down.png differ
diff --git a/res/drawable-mdpi/ic_scroll_down.png b/res/drawable-mdpi/ic_scroll_down.png
new file mode 100644
index 000000000..2b570d682
Binary files /dev/null and b/res/drawable-mdpi/ic_scroll_down.png differ
diff --git a/res/drawable-xhdpi/ic_scroll_down.png b/res/drawable-xhdpi/ic_scroll_down.png
new file mode 100644
index 000000000..a3e1b8cf7
Binary files /dev/null and b/res/drawable-xhdpi/ic_scroll_down.png differ
diff --git a/res/drawable-xxhdpi/ic_scroll_down.png b/res/drawable-xxhdpi/ic_scroll_down.png
new file mode 100644
index 000000000..4f3df9bb8
Binary files /dev/null and b/res/drawable-xxhdpi/ic_scroll_down.png differ
diff --git a/res/drawable-xxxhdpi/ic_scroll_down.png b/res/drawable-xxxhdpi/ic_scroll_down.png
new file mode 100644
index 000000000..569715e0a
Binary files /dev/null and b/res/drawable-xxxhdpi/ic_scroll_down.png differ
diff --git a/res/layout/conversation_fragment.xml b/res/layout/conversation_fragment.xml
index 9204d31a2..042b67746 100644
--- a/res/layout/conversation_fragment.xml
+++ b/res/layout/conversation_fragment.xml
@@ -2,7 +2,8 @@
+ android:layout_height="match_parent"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
-
-
-
+
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 3fa139d1b..72b4318cd 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -66,7 +66,4 @@
20sp
3dp
-
- 10dp
- 10dp
diff --git a/src/org/thoughtcrime/securesms/ConversationFragment.java b/src/org/thoughtcrime/securesms/ConversationFragment.java
index 69d2f061a..9193587d6 100644
--- a/src/org/thoughtcrime/securesms/ConversationFragment.java
+++ b/src/org/thoughtcrime/securesms/ConversationFragment.java
@@ -24,6 +24,7 @@ import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
+import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
@@ -44,6 +45,8 @@ import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
import android.widget.Toast;
import org.thoughtcrime.securesms.ConversationAdapter.ItemClickListener;
@@ -79,7 +82,6 @@ public class ConversationFragment extends Fragment
private final ActionModeCallback actionModeCallback = new ActionModeCallback();
private final ItemClickListener selectionClickListener = new ConversationFragmentItemClickListener();
- private final OnScrollListener scrollListener = new ConversationScrollListener();
private ConversationFragmentListener listener;
@@ -117,7 +119,6 @@ public class ConversationFragment extends Fragment
final LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, true);
list.setHasFixedSize(false);
list.setLayoutManager(layoutManager);
- list.addOnScrollListener(scrollListener);
list.setItemAnimator(null);
loadMoreView = inflater.inflate(R.layout.load_more_header, container, false);
@@ -173,8 +174,11 @@ public class ConversationFragment extends Fragment
}
private void initializeResources() {
- this.recipients = RecipientFactory.getRecipientsForIds(getActivity(), getActivity().getIntent().getLongArrayExtra("recipients"), true);
- this.threadId = this.getActivity().getIntent().getLongExtra("thread_id", -1);
+ this.recipients = RecipientFactory.getRecipientsForIds(getActivity(), getActivity().getIntent().getLongArrayExtra("recipients"), true);
+ this.threadId = this.getActivity().getIntent().getLongExtra("thread_id", -1);
+
+ OnScrollListener scrollListener = new ConversationScrollListener(getActivity());
+ list.addOnScrollListener(scrollListener);
}
private void initializeListAdapter() {
@@ -408,26 +412,39 @@ public class ConversationFragment extends Fragment
}
private class ConversationScrollListener extends OnScrollListener {
- private boolean wasAtBottom = true;
+
+ private final Animation scrollButtonInAnimation;
+ private final Animation scrollButtonOutAnimation;
+
+ private boolean wasAtBottom = true;
+ private boolean wasAtZoomScrollHeight = false;
+
+ ConversationScrollListener(@NonNull Context context) {
+ this.scrollButtonInAnimation = AnimationUtils.loadAnimation(context, R.anim.fade_scale_in);
+ this.scrollButtonOutAnimation = AnimationUtils.loadAnimation(context, R.anim.fade_scale_out);
+
+ this.scrollButtonInAnimation.setDuration(100);
+ this.scrollButtonOutAnimation.setDuration(50);
+ }
@Override
public void onScrolled(final RecyclerView rv, final int dx, final int dy) {
- boolean currentlyAtBottom = isAtBottom();
+ boolean currentlyAtBottom = isAtBottom();
+ boolean currentlyAtZoomScrollHeight = isAtZoomScrollHeight();
- if (wasAtBottom != currentlyAtBottom) {
- composeDivider.setVisibility(currentlyAtBottom ? View.INVISIBLE : View.VISIBLE);
- scrollToBottomButton.setVisibility(currentlyAtBottom ? View.INVISIBLE : View.VISIBLE);
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
- composeDivider.animate().alpha(currentlyAtBottom ? 0 : 1);
- scrollToBottomButton.animate().alpha(currentlyAtBottom ? 0 : 1);
- } else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) {
- composeDivider.setAlpha(currentlyAtBottom ? 0 : 1);
- scrollToBottomButton.setAlpha(currentlyAtBottom ? 0 : 1);
- }
-
- wasAtBottom = currentlyAtBottom;
+ if (currentlyAtBottom && !wasAtBottom) {
+ ViewUtil.fadeOut(composeDivider, 50, View.INVISIBLE);
+ ViewUtil.animateOut(scrollToBottomButton, scrollButtonOutAnimation, View.INVISIBLE);
+ } else if (!currentlyAtBottom && wasAtBottom) {
+ ViewUtil.fadeIn(composeDivider, 500);
}
+
+ if (currentlyAtZoomScrollHeight && !wasAtZoomScrollHeight) {
+ ViewUtil.animateIn(scrollToBottomButton, scrollButtonInAnimation);
+ }
+
+ wasAtBottom = currentlyAtBottom;
+ wasAtZoomScrollHeight = currentlyAtZoomScrollHeight;
}
private boolean isAtBottom() {
@@ -439,6 +456,10 @@ public class ConversationFragment extends Fragment
return isAtBottom && bottomView.getBottom() <= list.getHeight();
}
+
+ private boolean isAtZoomScrollHeight() {
+ return ((LinearLayoutManager) list.getLayoutManager()).findFirstCompletelyVisibleItemPosition() > 4;
+ }
}
private class ConversationFragmentItemClickListener implements ItemClickListener {