package com.amaze.filemanager.ui.views;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.InsetDrawable;
import android.graphics.drawable.StateListDrawable;
import android.support.annotation.AttrRes;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.OnScrollListener;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.amaze.filemanager.R;
import com.amaze.filemanager.utils.Utils;
public class FastScroller extends FrameLayout {
private View bar;
private ImageView handle;
private RecyclerView recyclerView;
private final ScrollListener scrollListener;
boolean manuallyChangingPosition = false;
int columns = 1;
private class ScrollListener extends OnScrollListener {
public void onScrolled(RecyclerView recyclerView, int i, int i2) {
if (handle != null && !manuallyChangingPosition) {
updateHandlePosition();
}
}
}
public FastScroller(@NonNull Context context, AttributeSet attributeSet) {
super(context, attributeSet);
this.scrollListener = new ScrollListener();
initialise(context);
}
public FastScroller(@NonNull Context context, AttributeSet attributeSet, int i) {
super(context, attributeSet, i);
this.scrollListener = new ScrollListener();
initialise(context);
}
private float computeHandlePosition() {
View firstVisibleView = recyclerView.getChildAt(0);
handle.setVisibility(VISIBLE);
float recyclerViewOversize; //how much is recyclerView bigger than fastScroller
int recyclerViewAbsoluteScroll;
if (firstVisibleView == null || recyclerView == null) return -1;
recyclerViewOversize = firstVisibleView.getHeight() / columns * recyclerView.getAdapter().getItemCount() - getHeightMinusPadding();
recyclerViewAbsoluteScroll = recyclerView.getChildLayoutPosition(firstVisibleView) / columns * firstVisibleView.getHeight() - firstVisibleView.getTop();
return recyclerViewAbsoluteScroll / recyclerViewOversize;
}
private int getHeightMinusPadding() {
return (getHeight() - getPaddingBottom()) - getPaddingTop();
}
private void initialise(@NonNull Context context) {
setClipChildren(false);
inflate(context, R.layout.fastscroller, this);
this.handle = (ImageView) findViewById(R.id.scroll_handle);
this.bar = findViewById(R.id.scroll_bar);
this.handle.setEnabled(true);
setPressedHandleColor(Utils.getColor(getContext(), R.color.accent_blue));
setUpBarBackground();
setVisibility(VISIBLE);
}
private void setHandlePosition1(float relativePos) {
handle.setY(Utils.clamp(
0, getHeightMinusPadding() - handle.getHeight(), relativePos * (getHeightMinusPadding() - handle.getHeight()))
);
}
private void setUpBarBackground() {
InsetDrawable insetDrawable;
int resolveColor = resolveColor(getContext(), R.attr.colorControlNormal);
insetDrawable = new InsetDrawable(new ColorDrawable(resolveColor), getResources().getDimensionPixelSize(R.dimen.fastscroller_track_padding), 0, 0, 0);
this.bar.setBackgroundDrawable(insetDrawable);
}
int resolveColor(@NonNull Context context, @AttrRes int i) {
TypedArray obtainStyledAttributes = context.obtainStyledAttributes(new int[]{i});
int color = obtainStyledAttributes.getColor(0, 0);
obtainStyledAttributes.recycle();
return color;
}
onTouchListener a;
public boolean onTouchEvent(@NonNull MotionEvent motionEvent) {
if (motionEvent.getAction() == 0 || motionEvent.getAction() == 2) {
this.handle.setPressed(true);
bar.setVisibility(VISIBLE);
float relativePos = getRelativeTouchPosition(motionEvent);
setHandlePosition1(relativePos);
manuallyChangingPosition = true;
setRecyclerViewPosition(relativePos);
// showIfHidden();
if (a != null) a.onTouch();
return true;
} else if (motionEvent.getAction() != 1) {
return super.onTouchEvent(motionEvent);
} else {
bar.setVisibility(INVISIBLE);
manuallyChangingPosition = false;
this.handle.setPressed(false);
// scheduleHide();
return true;
}
}
private void invalidateVisibility() {
if (recyclerView.getAdapter() == null || recyclerView.getAdapter().getItemCount() == 0 || recyclerView.getChildAt(0) == null ||
isRecyclerViewScrollable()
) {
setVisibility(INVISIBLE);
} else {
setVisibility(VISIBLE);
}
}
private boolean isRecyclerViewScrollable() {
return recyclerView.getChildAt(0).getHeight() * recyclerView.getAdapter().getItemCount() / columns <= getHeightMinusPadding() || recyclerView.getAdapter().getItemCount() / columns < 25;
}
private void setRecyclerViewPosition(float relativePos) {
if (recyclerView != null) {
int itemCount = recyclerView.getAdapter().getItemCount();
int targetPos = (int) Utils.clamp(0, itemCount - 1, (int) (relativePos * (float) itemCount));
recyclerView.smoothScrollToPosition(targetPos);
}
}
private float getRelativeTouchPosition(MotionEvent event) {
float yInParent = event.getRawY() - Utils.getViewRawY(handle);
return yInParent / (getHeightMinusPadding() - handle.getHeight());
}
public interface onTouchListener {
void onTouch();
}
public void registerOnTouchListener(onTouchListener onTouchListener) {
a = onTouchListener;
}
public void setPressedHandleColor(int i) {
handle.setColorFilter(i);
StateListDrawable stateListDrawable = new StateListDrawable();
Drawable drawable = ContextCompat.getDrawable(getContext(), R.drawable.fastscroller_handle_normal);
Drawable drawable1 = ContextCompat.getDrawable(getContext(), R.drawable.fastscroller_handle_pressed);
stateListDrawable.addState(View.PRESSED_ENABLED_STATE_SET, new InsetDrawable(drawable1, getResources().getDimensionPixelSize(R.dimen.fastscroller_track_padding), 0, 0, 0));
stateListDrawable.addState(View.EMPTY_STATE_SET, new InsetDrawable(drawable, getResources().getDimensionPixelSize(R.dimen.fastscroller_track_padding), 0, 0, 0));
this.handle.setImageDrawable(stateListDrawable);
}
public void setRecyclerView(@NonNull RecyclerView recyclerView, int columns) {
this.recyclerView = recyclerView;
this.columns = columns;
bar.setVisibility(INVISIBLE);
recyclerView.addOnScrollListener(this.scrollListener);
invalidateVisibility();
recyclerView.setOnHierarchyChangeListener(new OnHierarchyChangeListener() {
@Override
public void onChildViewAdded(View parent, View child) {
invalidateVisibility();
}
@Override
public void onChildViewRemoved(View parent, View child) {
invalidateVisibility();
}
});
}
void updateHandlePosition() {
setHandlePosition1(computeHandlePosition());
}
int vx1 = -1;
public void updateHandlePosition(int vx, int l) {
if (vx != vx1) {
setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), l + vx);
setHandlePosition1(computeHandlePosition());
vx1 = vx;
}
}
}