scroll *all* the way

fixes #4664
closes #4695
// FREEBIE
This commit is contained in:
Jake McGinty 2015-11-23 11:33:51 -08:00 committed by Moxie Marlinspike
parent d58f4d1232
commit a0beb7f0e0

View File

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