Fix snap helper
This commit is contained in:
parent
d02ea05865
commit
b36e581480
@ -1,5 +1,6 @@
|
||||
package org.fdroid.fdroid.views;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.LinearSnapHelper;
|
||||
@ -11,6 +12,9 @@ import static android.support.v7.widget.RecyclerView.NO_POSITION;
|
||||
|
||||
public class LinearLayoutManagerSnapHelper extends LinearSnapHelper {
|
||||
|
||||
private View mLastSavedTarget;
|
||||
private int mLastSavedDistance;
|
||||
|
||||
public interface LinearSnapHelperListener {
|
||||
/**
|
||||
* Tells the listener that we have selected a view to snap to.
|
||||
@ -36,29 +40,56 @@ public class LinearLayoutManagerSnapHelper extends LinearSnapHelper {
|
||||
@Override
|
||||
public View findSnapView(RecyclerView.LayoutManager layoutManager) {
|
||||
View snappedView = super.findSnapView(layoutManager);
|
||||
if (layoutManager.canScrollHorizontally()) {
|
||||
if (snappedView != null && layoutManager.canScrollHorizontally()) {
|
||||
if (layoutManager instanceof LinearLayoutManager) {
|
||||
mLastSavedTarget = null;
|
||||
|
||||
int distSnap = super.calculateDistanceToFinalSnap(layoutManager, snappedView)[0];
|
||||
|
||||
int firstChild = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();
|
||||
int lastChild = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
|
||||
if (firstChild == 0) {
|
||||
View child = layoutManager.findViewByPosition(firstChild);
|
||||
if (mOrientationHelper.getDecoratedEnd(child) >= mOrientationHelper.getDecoratedMeasurement(child) / 2
|
||||
&& mOrientationHelper.getDecoratedEnd(child) > 0) {
|
||||
int dist1 = super.calculateDistanceToFinalSnap(layoutManager, snappedView)[0];
|
||||
int dist2 = mOrientationHelper.getDecoratedStart(child);
|
||||
if (Math.abs(dist1) > Math.abs(dist2)) {
|
||||
snappedView = child;
|
||||
|
||||
int idxSnap = -1;
|
||||
for (int i = firstChild; i <= lastChild; i++) {
|
||||
View view = ((LinearLayoutManager) layoutManager).findViewByPosition(i);
|
||||
if (view == snappedView) {
|
||||
idxSnap = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int snapPositionFirst = mOrientationHelper.getDecoratedMeasurement(((LinearLayoutManager) layoutManager).findViewByPosition(firstChild)) / 2;
|
||||
int snapPositionLast = mOrientationHelper.getTotalSpace() - mOrientationHelper.getDecoratedMeasurement(((LinearLayoutManager) layoutManager).findViewByPosition(lastChild)) / 2;
|
||||
|
||||
int centerSnapPosition = mOrientationHelper.getTotalSpace() / 2;
|
||||
|
||||
if (idxSnap != -1) {
|
||||
int currentSmallestDistance = Integer.MAX_VALUE;
|
||||
View currentSmallestDistanceView = null;
|
||||
for (int i = firstChild; i <= lastChild; i++) {
|
||||
View view = ((LinearLayoutManager) layoutManager).findViewByPosition(i);
|
||||
if (i < idxSnap && firstChild == 0) {
|
||||
int snapPosition = snapPositionFirst + (i - firstChild) * (centerSnapPosition - snapPositionFirst) / (idxSnap - firstChild);
|
||||
int viewPosition = view.getLeft() + view.getWidth() / 2;
|
||||
int dist = snapPosition - viewPosition;
|
||||
if (Math.abs(dist) < Math.abs(currentSmallestDistance) || (Math.abs(dist) == Math.abs(currentSmallestDistance) && distSnap > 0)) {
|
||||
currentSmallestDistance = dist;
|
||||
currentSmallestDistanceView = view;
|
||||
}
|
||||
} else if (i > idxSnap && lastChild == (mLlm.getItemCount() - 1)) {
|
||||
int snapPosition = snapPositionLast - (lastChild - i) * (snapPositionLast - centerSnapPosition) / (lastChild - idxSnap);
|
||||
int viewPosition = view.getLeft() + view.getWidth() / 2;
|
||||
int dist = snapPosition - viewPosition;
|
||||
if (Math.abs(dist) < Math.abs(currentSmallestDistance) || (Math.abs(dist) == Math.abs(currentSmallestDistance) && distSnap < 0)) {
|
||||
currentSmallestDistance = dist;
|
||||
currentSmallestDistanceView = view;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (lastChild == (mLlm.getItemCount() - 1)) {
|
||||
View child = layoutManager.findViewByPosition(lastChild);
|
||||
if (mOrientationHelper.getDecoratedStart(child) < mOrientationHelper.getTotalSpace() - mOrientationHelper.getDecoratedMeasurement(child) / 2
|
||||
&& mOrientationHelper.getDecoratedStart(child) < mOrientationHelper.getTotalSpace()) {
|
||||
int dist1 = super.calculateDistanceToFinalSnap(layoutManager, snappedView)[0];
|
||||
int dist2 = mOrientationHelper.getTotalSpace() - mOrientationHelper.getDecoratedEnd(child);
|
||||
if (Math.abs(dist1) > Math.abs(dist2)) {
|
||||
snappedView = child;
|
||||
}
|
||||
if (Math.abs(distSnap) > Math.abs(currentSmallestDistance)) {
|
||||
snappedView = currentSmallestDistanceView;
|
||||
mLastSavedTarget = currentSmallestDistanceView;
|
||||
mLastSavedDistance = -currentSmallestDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -71,4 +102,15 @@ public class LinearLayoutManagerSnapHelper extends LinearSnapHelper {
|
||||
}
|
||||
return snappedView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] calculateDistanceToFinalSnap(@NonNull RecyclerView.LayoutManager layoutManager, @NonNull View targetView) {
|
||||
if (targetView == mLastSavedTarget) {
|
||||
int[] out = new int[2];
|
||||
out[0] = mLastSavedDistance;
|
||||
out[1] = 0;
|
||||
return out;
|
||||
}
|
||||
return super.calculateDistanceToFinalSnap(layoutManager, targetView);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user