新版Android系统(API 25)中,NestedScrollView可能会出现滑动停止的bug。

18

我在 Nexus 5x (7.1.2) 和 Google Pixel (7.1.1) 上使用 NestedScrollView 滑动时遇到了奇怪的问题,在其他操作系统版本上它运行正常。

有时候,滑动动画在松开手指后就会停止。它会被卡住,接下来的几次滑动可能也会停止。 为了重现这个问题,您需要多次向上和向下滑动。

在日志中,这些滑动看起来基本相同,包括速度、方向等等,所以我找不到这个错误的真正原因。

此外,NestedScrollView 不一定要在 CoordinatorLayout 内部,它也可以完全没有 NestedScrollingChild。

例如,这个 bug 可以通过以下 NestedScrollView 的子项之一重现:

1)LinearLayout 中填充着 TextViews

2)WebView

3)LinearLayout 中填充着 RecyclerViews。

我知道关于 CoordinatorLayout 中 RecyclerView 和 Behaviours 可能存在的问题,但与此无关。所以请不要提及它们。

recyclerView.getLayoutManager().setAutoMeasureEnabled(true);
recyclerView.setNestedScrollingEnabled(false);

或类似的事情。

代码示例:

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:text="Put a super long text here"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:text="Put a super long text here"/>

    </LinearLayout>

</android.support.v4.widget.NestedScrollView>

1
似乎支持库中存在一个错误 https://code.google.com/p/android/issues/detail?id=183738 该链接来自于此回复,他们说你可以“模拟”这种行为 https://dev59.com/vVwZ5IYBdhLWcg3wJ9Yp - eduyayo
1
我也可以确认这个问题。非常容易重现,只需创建一个包含任何内容的NestedScrollView即可。与普通的ScrollView相比,当您快速向上和向下滑动时,它经常会立即停止滚动。我将创建一个repo,让您可以快速比较这两种情况。 - Gillis Haasnoot
1
我创建了一个仓库,您可以在其中快速测试嵌套滚动视图和普通滚动视图的不同行为。 https://github.com/holoduke/nestedscrollviewtest - Gillis Haasnoot
@GillisHaasnoot 非常感谢。如果您不介意的话,我会添加到相应的Google跟踪问题中。 编辑:啊,您已经完成了 :) - Dimezis
1
现在应该已经修复了:https://chris.banes.me/2017/06/09/carry-on-scrolling/ - granko87
显示剩余5条评论
2个回答

7

显然这是NestedScrollView中的一个错误。 我已经为此制定了一种解决方法,但仍在等待Google方面进行适当修复。

https://github.com/Dimezis/FlingableNestedScrollView/

编辑:

看起来这个问题已经在支持库26.0.0-beta2中得到了修复。

https://chris.banes.me/2017/06/09/carry-on-scrolling/

编辑 2: 尽管现在滚动工作正常,但在我的应用程序中,我可以不断重现此错误:

https://issuetracker.google.com/issues/37051723

如果有人也遇到了这个问题,可以在提到的线程中找到一个解决方法。


这对我帮助很大。谢谢 :) - sauvik
支持库26仍存在问题。足以看出由Android Studio创建的Android项目“ScrollingActivity”和Google IO应用程序在滚动时出现错误。 - David

0
根据滚动手势动画教程,在重写computeScroll()方法之后,使用mScroller.computeScrollOffset()来计算适当的偏移量以进行滚动视图,需要使用:
ViewCompat.postInvalidateOnAnimation(this);

实现下一个滚动的动画。 但是在NestedScrollView中,computeScroll()看起来像这样:

public void computeScroll() {
    if (mScroller.computeScrollOffset()) {
    ...     
    }
}

它不请求下一个滚动动画!这意味着在使用mScroller.fling(...)之后,computeScroll()方法有时只会被调用一次,视图不会保持fling。

为了解决这个问题,我尝试以这种方式替换computeScroll:

public void computeScroll(){
    if(mScroller.computeScrollOffset()){
       ...
       ViewCompat.postInvalidateOnAnimation(this); 
    }
}

这可能不是一个好的解决方案,但目前它可以很好地工作。

NestedScrollView的最新版本已经添加了ViewCompat.postInvalidateOnAnimation(this)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接