Merge pull request #2672 from yausername/videoDetailscrollFix
Fix scrolling in video detail fragment. Fixes #2627 and #2437
This commit is contained in:
commit
7e4becd6b6
|
@ -77,7 +77,6 @@ dependencies {
|
||||||
|
|
||||||
implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
|
implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
|
||||||
implementation 'de.hdodenhof:circleimageview:2.2.0'
|
implementation 'de.hdodenhof:circleimageview:2.2.0'
|
||||||
implementation 'com.github.nirhart:ParallaxScroll:dd53d1f9d1'
|
|
||||||
implementation 'com.nononsenseapps:filepicker:4.2.1'
|
implementation 'com.nononsenseapps:filepicker:4.2.1'
|
||||||
|
|
||||||
implementation "com.google.android.exoplayer:exoplayer:${exoPlayerLibVersion}"
|
implementation "com.google.android.exoplayer:exoplayer:${exoPlayerLibVersion}"
|
||||||
|
|
|
@ -1,116 +1,80 @@
|
||||||
package android.support.design.widget;
|
package android.support.design.widget;
|
||||||
|
|
||||||
import android.animation.ValueAnimator;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.design.animation.AnimationUtils;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.View;
|
import android.view.MotionEvent;
|
||||||
|
import android.widget.OverScroller;
|
||||||
|
|
||||||
// check this https://github.com/ToDou/appbarlayout-spring-behavior/blob/master/appbarspring/src/main/java/android/support/design/widget/AppBarFlingFixBehavior.java
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
// check this https://stackoverflow.com/questions/56849221/recyclerview-fling-causes-laggy-while-appbarlayout-is-scrolling/57997489#57997489
|
||||||
public final class FlingBehavior extends AppBarLayout.Behavior {
|
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) {
|
public FlingBehavior(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed, int type) {
|
public boolean onInterceptTouchEvent(CoordinatorLayout parent, AppBarLayout child, MotionEvent ev) {
|
||||||
if (dy != 0) {
|
switch (ev.getActionMasked()) {
|
||||||
int val = child.getBottom();
|
case MotionEvent.ACTION_DOWN:
|
||||||
if (val != 0) {
|
// remove reference to old nested scrolling child
|
||||||
int min, max;
|
resetNestedScrollingChild();
|
||||||
if (dy < 0) {
|
// Stop fling when your finger touches the screen
|
||||||
// We're scrolling down
|
stopAppBarLayoutFling();
|
||||||
} else {
|
break;
|
||||||
// We're scrolling up
|
default:
|
||||||
if (mOffsetAnimator != null && mOffsetAnimator.isRunning()) {
|
break;
|
||||||
mOffsetAnimator.cancel();
|
}
|
||||||
}
|
return super.onInterceptTouchEvent(parent, child, ev);
|
||||||
min = -child.getUpNestedPreScrollRange();
|
}
|
||||||
max = 0;
|
|
||||||
consumed[1] = scroll(coordinatorLayout, child, dy, min, max);
|
@Nullable
|
||||||
}
|
private OverScroller getScrollerField() {
|
||||||
|
try {
|
||||||
|
Class<?> headerBehaviorType = this.getClass().getSuperclass().getSuperclass().getSuperclass();
|
||||||
|
if (headerBehaviorType != null) {
|
||||||
|
Field field = headerBehaviorType.getDeclaredField("scroller");
|
||||||
|
field.setAccessible(true);
|
||||||
|
return ((OverScroller) field.get(this));
|
||||||
|
}
|
||||||
|
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||||
|
// ?
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Field getLastNestedScrollingChildRefField() {
|
||||||
|
try {
|
||||||
|
Class<?> headerBehaviorType = this.getClass().getSuperclass().getSuperclass();
|
||||||
|
if (headerBehaviorType != null) {
|
||||||
|
Field field = headerBehaviorType.getDeclaredField("lastNestedScrollingChildRef");
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
// ?
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetNestedScrollingChild(){
|
||||||
|
Field field = getLastNestedScrollingChildRefField();
|
||||||
|
if(field != null){
|
||||||
|
try {
|
||||||
|
Object value = field.get(this);
|
||||||
|
if(value != null) field.set(this, null);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
// ?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void stopAppBarLayoutFling() {
|
||||||
public boolean onNestedPreFling(@NonNull CoordinatorLayout coordinatorLayout, @NonNull AppBarLayout child, @NonNull View target, float velocityX, float velocityY) {
|
OverScroller scroller = getScrollerField();
|
||||||
|
if (scroller != null) scroller.forceFinished(true);
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -36,7 +36,6 @@ public class AboutActivity extends AppCompatActivity {
|
||||||
new SoftwareComponent("ACRA", "2013", "Kevin Gaudin", "http://www.acra.ch", StandardLicenses.APACHE2),
|
new SoftwareComponent("ACRA", "2013", "Kevin Gaudin", "http://www.acra.ch", StandardLicenses.APACHE2),
|
||||||
new SoftwareComponent("Universal Image Loader", "2011 - 2015", "Sergey Tarasevich", "https://github.com/nostra13/Android-Universal-Image-Loader", StandardLicenses.APACHE2),
|
new SoftwareComponent("Universal Image Loader", "2011 - 2015", "Sergey Tarasevich", "https://github.com/nostra13/Android-Universal-Image-Loader", StandardLicenses.APACHE2),
|
||||||
new SoftwareComponent("CircleImageView", "2014 - 2017", "Henning Dodenhof", "https://github.com/hdodenhof/CircleImageView", StandardLicenses.APACHE2),
|
new SoftwareComponent("CircleImageView", "2014 - 2017", "Henning Dodenhof", "https://github.com/hdodenhof/CircleImageView", StandardLicenses.APACHE2),
|
||||||
new SoftwareComponent("ParalaxScrollView", "2014", "Nir Hartmann", "https://github.com/nirhart/ParallaxScroll", StandardLicenses.MIT),
|
|
||||||
new SoftwareComponent("NoNonsense-FilePicker", "2016", "Jonas Kalderstam", "https://github.com/spacecowboy/NoNonsense-FilePicker", StandardLicenses.MPL2),
|
new SoftwareComponent("NoNonsense-FilePicker", "2016", "Jonas Kalderstam", "https://github.com/spacecowboy/NoNonsense-FilePicker", StandardLicenses.MPL2),
|
||||||
new SoftwareComponent("ExoPlayer", "2014-2017", "Google Inc", "https://github.com/google/ExoPlayer", StandardLicenses.APACHE2),
|
new SoftwareComponent("ExoPlayer", "2014-2017", "Google Inc", "https://github.com/google/ExoPlayer", StandardLicenses.APACHE2),
|
||||||
new SoftwareComponent("RxAndroid", "2015", "The RxAndroid authors", "https://github.com/ReactiveX/RxAndroid", StandardLicenses.APACHE2),
|
new SoftwareComponent("RxAndroid", "2015", "The RxAndroid authors", "https://github.com/ReactiveX/RxAndroid", StandardLicenses.APACHE2),
|
||||||
|
|
|
@ -93,7 +93,7 @@ public class CommentsFragment extends BaseListInfoFragment<CommentsInfo> {
|
||||||
public void handleResult(@NonNull CommentsInfo result) {
|
public void handleResult(@NonNull CommentsInfo result) {
|
||||||
super.handleResult(result);
|
super.handleResult(result);
|
||||||
|
|
||||||
AnimationUtils.slideUp(getView(),120, 96, 0.06f);
|
AnimationUtils.slideUp(getView(),120, 150, 0.06f);
|
||||||
|
|
||||||
if (!result.getErrors().isEmpty()) {
|
if (!result.getErrors().isEmpty()) {
|
||||||
showSnackBarError(result.getErrors(), UserAction.REQUESTED_COMMENTS, NewPipe.getNameOfService(result.getServiceId()), result.getUrl(), 0);
|
showSnackBarError(result.getErrors(), UserAction.REQUESTED_COMMENTS, NewPipe.getNameOfService(result.getServiceId()), result.getUrl(), 0);
|
||||||
|
|
|
@ -130,24 +130,24 @@
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:text="12:38"
|
tools:text="12:38"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<org.schabi.newpipe.views.AnimatedProgressBar
|
||||||
|
android:id="@+id/position_view"
|
||||||
|
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="2dp"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:progressDrawable="?attr/progress_horizontal_drawable"
|
||||||
|
android:visibility="invisible"
|
||||||
|
tools:max="100"
|
||||||
|
tools:progress="40"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
</android.support.design.widget.CollapsingToolbarLayout>
|
</android.support.design.widget.CollapsingToolbarLayout>
|
||||||
|
|
||||||
<org.schabi.newpipe.views.AnimatedProgressBar
|
|
||||||
android:id="@+id/position_view"
|
|
||||||
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="4dp"
|
|
||||||
android:layout_marginTop="-2dp"
|
|
||||||
android:background="@android:color/transparent"
|
|
||||||
android:progressDrawable="?attr/progress_horizontal_drawable"
|
|
||||||
android:visibility="invisible"
|
|
||||||
app:layout_scrollFlags="scroll"
|
|
||||||
tools:max="100"
|
|
||||||
tools:progress="40"
|
|
||||||
tools:visibility="visible" />
|
|
||||||
|
|
||||||
<!-- CONTENT -->
|
<!-- CONTENT -->
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:id="@+id/detail_content_root_layout"
|
android:id="@+id/detail_content_root_layout"
|
||||||
|
|
|
@ -128,23 +128,22 @@
|
||||||
tools:text="12:38"
|
tools:text="12:38"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<org.schabi.newpipe.views.AnimatedProgressBar
|
||||||
|
android:id="@+id/position_view"
|
||||||
|
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="2dp"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:progressDrawable="?attr/progress_horizontal_drawable"
|
||||||
|
android:visibility="invisible"
|
||||||
|
tools:max="100"
|
||||||
|
tools:progress="40"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
</android.support.design.widget.CollapsingToolbarLayout>
|
</android.support.design.widget.CollapsingToolbarLayout>
|
||||||
|
|
||||||
<org.schabi.newpipe.views.AnimatedProgressBar
|
|
||||||
android:id="@+id/position_view"
|
|
||||||
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="4dp"
|
|
||||||
android:layout_marginTop="-2dp"
|
|
||||||
android:progressDrawable="?attr/progress_horizontal_drawable"
|
|
||||||
android:visibility="invisible"
|
|
||||||
app:layout_scrollFlags="scroll"
|
|
||||||
tools:max="100"
|
|
||||||
tools:progress="40"
|
|
||||||
tools:visibility="visible" />
|
|
||||||
|
|
||||||
<!-- CONTENT -->
|
<!-- CONTENT -->
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:id="@+id/detail_content_root_layout"
|
android:id="@+id/detail_content_root_layout"
|
||||||
|
|
Loading…
Reference in New Issue