mirror of https://github.com/TeamNewPipe/NewPipe
116 lines
4.5 KiB
Java
116 lines
4.5 KiB
Java
package android.support.design.widget;
|
|
|
|
import android.animation.ValueAnimator;
|
|
import android.content.Context;
|
|
import android.support.annotation.NonNull;
|
|
import android.support.design.animation.AnimationUtils;
|
|
import android.util.AttributeSet;
|
|
import android.view.View;
|
|
|
|
// check this https://github.com/ToDou/appbarlayout-spring-behavior/blob/master/appbarspring/src/main/java/android/support/design/widget/AppBarFlingFixBehavior.java
|
|
public final class FlingBehavior extends AppBarLayout.Behavior {
|
|
|
|
private ValueAnimator mOffsetAnimator;
|
|
private static final int MAX_OFFSET_ANIMATION_DURATION = 600; // ms
|
|
|
|
public FlingBehavior() {
|
|
}
|
|
|
|
public FlingBehavior(Context context, AttributeSet attrs) {
|
|
super(context, attrs);
|
|
}
|
|
|
|
@Override
|
|
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed, int type) {
|
|
if (dy != 0) {
|
|
int val = child.getBottom();
|
|
if (val != 0) {
|
|
int min, max;
|
|
if (dy < 0) {
|
|
// We're scrolling down
|
|
} else {
|
|
// We're scrolling up
|
|
if (mOffsetAnimator != null && mOffsetAnimator.isRunning()) {
|
|
mOffsetAnimator.cancel();
|
|
}
|
|
min = -child.getUpNestedPreScrollRange();
|
|
max = 0;
|
|
consumed[1] = scroll(coordinatorLayout, child, dy, min, max);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean onNestedPreFling(@NonNull CoordinatorLayout coordinatorLayout, @NonNull AppBarLayout child, @NonNull View target, float velocityX, float velocityY) {
|
|
|
|
if (velocityY != 0) {
|
|
if (velocityY < 0) {
|
|
// We're flinging down
|
|
int val = child.getBottom();
|
|
if (val != 0) {
|
|
final int targetScroll =
|
|
+child.getDownNestedPreScrollRange();
|
|
animateOffsetTo(coordinatorLayout, child, targetScroll, velocityY);
|
|
}
|
|
|
|
} else {
|
|
// We're flinging up
|
|
int val = child.getBottom();
|
|
if (val != 0) {
|
|
final int targetScroll = -child.getUpNestedPreScrollRange();
|
|
if (getTopBottomOffsetForScrollingSibling() > targetScroll) {
|
|
animateOffsetTo(coordinatorLayout, child, targetScroll, velocityY);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY);
|
|
}
|
|
|
|
private void animateOffsetTo(final CoordinatorLayout coordinatorLayout,
|
|
final AppBarLayout child, final int offset, float velocity) {
|
|
final int distance = Math.abs(getTopBottomOffsetForScrollingSibling() - offset);
|
|
|
|
final int duration;
|
|
velocity = Math.abs(velocity);
|
|
if (velocity > 0) {
|
|
duration = 3 * Math.round(1000 * (distance / velocity));
|
|
} else {
|
|
final float distanceRatio = (float) distance / child.getHeight();
|
|
duration = (int) ((distanceRatio + 1) * 150);
|
|
}
|
|
|
|
animateOffsetWithDuration(coordinatorLayout, child, offset, duration);
|
|
}
|
|
|
|
private void animateOffsetWithDuration(final CoordinatorLayout coordinatorLayout,
|
|
final AppBarLayout child, final int offset, final int duration) {
|
|
final int currentOffset = getTopBottomOffsetForScrollingSibling();
|
|
if (currentOffset == offset) {
|
|
if (mOffsetAnimator != null && mOffsetAnimator.isRunning()) {
|
|
mOffsetAnimator.cancel();
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (mOffsetAnimator == null) {
|
|
mOffsetAnimator = new ValueAnimator();
|
|
mOffsetAnimator.setInterpolator(AnimationUtils.DECELERATE_INTERPOLATOR);
|
|
mOffsetAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
|
@Override
|
|
public void onAnimationUpdate(ValueAnimator animator) {
|
|
setHeaderTopBottomOffset(coordinatorLayout, child,
|
|
(Integer) animator.getAnimatedValue());
|
|
}
|
|
});
|
|
} else {
|
|
mOffsetAnimator.cancel();
|
|
}
|
|
|
|
mOffsetAnimator.setDuration(Math.min(duration, MAX_OFFSET_ANIMATION_DURATION));
|
|
mOffsetAnimator.setIntValues(currentOffset, offset);
|
|
mOffsetAnimator.start();
|
|
}
|
|
} |