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