diff --git a/src/org/thoughtcrime/securesms/components/RecyclerViewFastScroller.java b/src/org/thoughtcrime/securesms/components/RecyclerViewFastScroller.java index 3eed8e0ab7..f10f08bce6 100644 --- a/src/org/thoughtcrime/securesms/components/RecyclerViewFastScroller.java +++ b/src/org/thoughtcrime/securesms/components/RecyclerViewFastScroller.java @@ -25,10 +25,10 @@ import android.annotation.TargetApi; import android.content.Context; import android.os.Build.VERSION; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; -import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewTreeObserver; @@ -43,21 +43,22 @@ public class RecyclerViewFastScroller extends LinearLayout { private static final int BUBBLE_ANIMATION_DURATION = 100; private static final int TRACK_SNAP_RANGE = 5; - private TextView bubble; - private View handle; - private RecyclerView recyclerView; + private @NonNull TextView bubble; + private @NonNull View handle; + private @Nullable RecyclerView recyclerView; + private int height; private ObjectAnimator currentAnimator; private final RecyclerView.OnScrollListener onScrollListener = new RecyclerView.OnScrollListener() { @Override public void onScrolled(final RecyclerView recyclerView, final int dx, final int dy) { - if (bubble == null || handle.isSelected()) - return; - final int verticalScrollOffset = recyclerView.computeVerticalScrollOffset(); - final int verticalScrollRange = recyclerView.computeVerticalScrollRange(); - final float proportion = (float)verticalScrollOffset / verticalScrollRange; - setBubbleAndHandlePosition(proportion); + if (handle.isSelected()) return; + final int offset = recyclerView.computeVerticalScrollOffset(); + final int range = recyclerView.computeVerticalScrollRange(); + final int extent = recyclerView.computeVerticalScrollExtent(); + final int offsetRange = Math.max(range - extent, 1); + setBubbleAndHandlePosition((float) Util.clamp(offset, 0, offsetRange) / offsetRange); } }; @@ -117,15 +118,17 @@ public class RecyclerViewFastScroller extends LinearLayout { return super.onTouchEvent(event); } - public void setRecyclerView(final RecyclerView recyclerView) { + public void setRecyclerView(final @NonNull RecyclerView recyclerView) { + if (this.recyclerView != null) { + this.recyclerView.removeOnScrollListener(onScrollListener); + } this.recyclerView = recyclerView; recyclerView.addOnScrollListener(onScrollListener); recyclerView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { recyclerView.getViewTreeObserver().removeOnPreDrawListener(this); - if (bubble == null || handle.isSelected()) - return true; + if (handle.isSelected()) return true; final int verticalScrollOffset = recyclerView.computeVerticalScrollOffset(); final int verticalScrollRange = recyclerView.computeVerticalScrollRange(); float proportion = (float)verticalScrollOffset / ((float)verticalScrollRange - height); @@ -157,8 +160,7 @@ public class RecyclerViewFastScroller extends LinearLayout { final int targetPos = Util.clamp((int)(proportion * (float)itemCount), 0, itemCount - 1); ((LinearLayoutManager) recyclerView.getLayoutManager()).scrollToPositionWithOffset(targetPos, 0); final CharSequence bubbleText = ((FastScrollAdapter) recyclerView.getAdapter()).getBubbleText(targetPos); - if (bubble != null) - bubble.setText(bubbleText); + bubble.setText(bubbleText); } }