aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/src/main/java/github/daneren2005/dsub/view/FastScroller.java75
1 files changed, 72 insertions, 3 deletions
diff --git a/app/src/main/java/github/daneren2005/dsub/view/FastScroller.java b/app/src/main/java/github/daneren2005/dsub/view/FastScroller.java
index bdfde1cf..ba83e46c 100644
--- a/app/src/main/java/github/daneren2005/dsub/view/FastScroller.java
+++ b/app/src/main/java/github/daneren2005/dsub/view/FastScroller.java
@@ -23,6 +23,7 @@ import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.AdapterDataObserver;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
@@ -45,6 +46,9 @@ public class FastScroller extends LinearLayout {
private RecyclerView recyclerView;
private final ScrollListener scrollListener = new ScrollListener();
private int height;
+ private int visibleRange = -1;
+ private RecyclerView.Adapter adapter;
+ private AdapterDataObserver adapterObserver;
private boolean visibleBubble = true;
private boolean hasScrolled = false;
@@ -80,6 +84,7 @@ public class FastScroller extends LinearLayout {
protected void onSizeChanged(int w,int h,int oldw,int oldh) {
super.onSizeChanged(w,h,oldw,oldh);
height = h;
+ visibleRange = -1;
}
@Override
@@ -121,10 +126,13 @@ public class FastScroller extends LinearLayout {
public void attachRecyclerView(RecyclerView recyclerView) {
this.recyclerView = recyclerView;
recyclerView.addOnScrollListener(scrollListener);
+ registerAdapter();
+ visibleRange = -1;
}
public void detachRecyclerView() {
recyclerView.removeOnScrollListener(scrollListener);
recyclerView.setVerticalScrollBarEnabled(true);
+ unregisterAdapter();
recyclerView = null;
setVisibility(View.GONE);
}
@@ -147,7 +155,12 @@ public class FastScroller extends LinearLayout {
((LinearLayoutManager)recyclerView.getLayoutManager()).scrollToPositionWithOffset(targetPos,0);
try {
- String bubbleText = ((BubbleTextGetter) recyclerView.getAdapter()).getTextToShowInBubble(targetPos);
+ String bubbleText = null;
+ RecyclerView.Adapter adapter = recyclerView.getAdapter();
+ if(adapter instanceof BubbleTextGetter) {
+ bubbleText = ((BubbleTextGetter) adapter).getTextToShowInBubble(targetPos);
+ }
+
if(bubbleText == null) {
visibleBubble = false;
bubble.setVisibility(View.INVISIBLE);
@@ -203,16 +216,72 @@ public class FastScroller extends LinearLayout {
currentAnimator.start();
}
+ private void registerAdapter() {
+ RecyclerView.Adapter newAdapter = recyclerView.getAdapter();
+ if(newAdapter != adapter) {
+ unregisterAdapter();
+ }
+
+ if(newAdapter != null) {
+ adapterObserver = new AdapterDataObserver() {
+ @Override
+ public void onChanged() {
+ visibleRange = -1;
+ }
+
+ @Override
+ public void onItemRangeChanged(int positionStart, int itemCount) {
+ visibleRange = -1;
+ }
+
+ @Override
+ public void onItemRangeInserted(int positionStart, int itemCount) {
+ visibleRange = -1;
+ }
+
+ @Override
+ public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
+ visibleRange = -1;
+ }
+
+ @Override
+ public void onItemRangeRemoved(int positionStart, int itemCount) {
+ visibleRange = -1;
+ }
+ };
+ newAdapter.registerAdapterDataObserver(adapterObserver);
+ adapter = newAdapter;
+ }
+ }
+ private void unregisterAdapter() {
+ if(adapter != null) {
+ adapter.unregisterAdapterDataObserver(adapterObserver);
+ adapter = null;
+ adapterObserver = null;
+ }
+ }
+
private class ScrollListener extends OnScrollListener {
@Override
public void onScrolled(RecyclerView rv,int dx,int dy) {
+ registerAdapter();
+
View firstVisibleView = recyclerView.getChildAt(0);
int firstVisiblePosition = recyclerView.getChildPosition(firstVisibleView);
- int visibleRange = recyclerView.getChildCount();
+ if(visibleRange == -1) {
+ visibleRange = recyclerView.getChildCount();
+ }
int itemCount = recyclerView.getAdapter().getItemCount();
+ int columns = Math.round(recyclerView.getWidth() / firstVisibleView.getWidth());
// Add the percentage of the item the user has scrolled past already
- float position = firstVisiblePosition + (-firstVisibleView.getY() / firstVisibleView.getHeight());
+ float pastFirst = -firstVisibleView.getY() / firstVisibleView.getHeight() * columns;
+ float position = firstVisiblePosition + pastFirst;
+
+ // Scale this so as we move down the visible range gets added to position from 0 -> visible range
+ float scaledVisibleRange = position / (float) (itemCount - visibleRange) * visibleRange;
+ position += scaledVisibleRange;
+
float proportion = position / itemCount;
setBubbleAndHandlePosition(height * proportion);