Fix occasional double scroll bar on fast scroller.

This commit is contained in:
Alan Evans 2019-08-12 15:05:49 -04:00 committed by Greyson Parrelli
parent 6352f7baf4
commit 4e6798e38e
3 changed files with 50 additions and 54 deletions

View File

@ -32,7 +32,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:visibility="gone" android:visibility="gone"
android:layout_gravity="end"/> android:layout_gravity="end"
tools:visibility="visible" />
<LinearLayout android:id="@+id/show_contacts_container" <LinearLayout android:id="@+id/show_contacts_container"
android:layout_width="wrap_content" android:layout_width="wrap_content"

View File

@ -231,6 +231,9 @@ public class ContactSelectionListFragment extends Fragment
if (useFastScroller) { if (useFastScroller) {
fastScroller.setVisibility(View.VISIBLE); fastScroller.setVisibility(View.VISIBLE);
fastScroller.setRecyclerView(recyclerView); fastScroller.setRecyclerView(recyclerView);
} else {
fastScroller.setRecyclerView(null);
fastScroller.setVisibility(View.GONE);
} }
} }

View File

@ -21,13 +21,7 @@ package org.thoughtcrime.securesms.components;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator; import android.animation.ObjectAnimator;
import android.annotation.TargetApi;
import android.content.Context; import android.content.Context;
import android.os.Build.VERSION;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
@ -35,17 +29,22 @@ import android.view.ViewTreeObserver;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.util.Util; import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil; import org.thoughtcrime.securesms.util.ViewUtil;
public class RecyclerViewFastScroller extends LinearLayout { public final 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 @NonNull TextView bubble; @NonNull private final TextView bubble;
private @NonNull View handle; @NonNull private final View handle;
private @Nullable RecyclerView recyclerView; @Nullable private RecyclerView recyclerView;
private int height; private int height;
private ObjectAnimator currentAnimator; private ObjectAnimator currentAnimator;
@ -87,7 +86,6 @@ public class RecyclerViewFastScroller extends LinearLayout {
} }
@Override @Override
@TargetApi(11)
public boolean onTouchEvent(@NonNull MotionEvent event) { public boolean onTouchEvent(@NonNull MotionEvent event) {
final int action = event.getAction(); final int action = event.getAction();
switch (action) { switch (action) {
@ -119,24 +117,26 @@ public class RecyclerViewFastScroller extends LinearLayout {
return super.onTouchEvent(event); return super.onTouchEvent(event);
} }
public void setRecyclerView(final @NonNull RecyclerView recyclerView) { public void setRecyclerView(final @Nullable RecyclerView recyclerView) {
if (this.recyclerView != null) { if (this.recyclerView != null) {
this.recyclerView.removeOnScrollListener(onScrollListener); this.recyclerView.removeOnScrollListener(onScrollListener);
} }
this.recyclerView = recyclerView; this.recyclerView = recyclerView;
recyclerView.addOnScrollListener(onScrollListener); if (recyclerView != null) {
recyclerView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { recyclerView.addOnScrollListener(onScrollListener);
@Override recyclerView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() { @Override
recyclerView.getViewTreeObserver().removeOnPreDrawListener(this); public boolean onPreDraw() {
if (handle.isSelected()) return true; recyclerView.getViewTreeObserver().removeOnPreDrawListener(this);
final int verticalScrollOffset = recyclerView.computeVerticalScrollOffset(); if (handle.isSelected()) return true;
final int verticalScrollRange = recyclerView.computeVerticalScrollRange(); final int verticalScrollOffset = recyclerView.computeVerticalScrollOffset();
float proportion = (float)verticalScrollOffset / ((float)verticalScrollRange - height); final int verticalScrollRange = recyclerView.computeVerticalScrollRange();
setBubbleAndHandlePosition(height * proportion); float proportion = (float)verticalScrollOffset / ((float)verticalScrollRange - height);
return true; setBubbleAndHandlePosition(height * proportion);
} return true;
}); }
});
}
} }
@Override @Override
@ -175,39 +175,31 @@ public class RecyclerViewFastScroller extends LinearLayout {
height - bubbleHeight)); height - bubbleHeight));
} }
@TargetApi(11)
private void showBubble() { private void showBubble() {
bubble.setVisibility(VISIBLE); bubble.setVisibility(VISIBLE);
if (VERSION.SDK_INT >= 11) { if (currentAnimator != null) currentAnimator.cancel();
if (currentAnimator != null) currentAnimator.cancel(); currentAnimator = ObjectAnimator.ofFloat(bubble, "alpha", 0f, 1f).setDuration(BUBBLE_ANIMATION_DURATION);
currentAnimator = ObjectAnimator.ofFloat(bubble, "alpha", 0f, 1f).setDuration(BUBBLE_ANIMATION_DURATION); currentAnimator.start();
currentAnimator.start();
}
} }
@TargetApi(11)
private void hideBubble() { private void hideBubble() {
if (VERSION.SDK_INT >= 11) { if (currentAnimator != null) currentAnimator.cancel();
if (currentAnimator != null) currentAnimator.cancel(); currentAnimator = ObjectAnimator.ofFloat(bubble, "alpha", 1f, 0f).setDuration(BUBBLE_ANIMATION_DURATION);
currentAnimator = ObjectAnimator.ofFloat(bubble, "alpha", 1f, 0f).setDuration(BUBBLE_ANIMATION_DURATION); currentAnimator.addListener(new AnimatorListenerAdapter() {
currentAnimator.addListener(new AnimatorListenerAdapter() { @Override
@Override public void onAnimationEnd(Animator animation) {
public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation);
super.onAnimationEnd(animation); bubble.setVisibility(INVISIBLE);
bubble.setVisibility(INVISIBLE); currentAnimator = null;
currentAnimator = null; }
}
@Override @Override
public void onAnimationCancel(Animator animation) { public void onAnimationCancel(Animator animation) {
super.onAnimationCancel(animation); super.onAnimationCancel(animation);
bubble.setVisibility(INVISIBLE); bubble.setVisibility(INVISIBLE);
currentAnimator = null; currentAnimator = null;
} }
}); });
currentAnimator.start(); currentAnimator.start();
} else {
bubble.setVisibility(INVISIBLE);
}
} }
} }