Reputation: 1595
I have a strange issue with NestedScrollView fling on Nexus 5x (7.1.2) and Google Pixel (7.1.1). On other OS versions it works OK.
Fling animation sometimes stops right after lifting up a finger. It stucks and the next few flings may be stopping as well. In order to reproduce it, you need to fling several times up and down.
In logs these flings look pretty much the same in terms of velocity, direction, etc, so I can't find a real cause of this bug.
Also NestedScrollView
doesn't necessarily need to be inside of CoordinatorLayout
, it also can have no NestedScrollingChild
at all.
For example, this bug is reproducible with one of the following NestedScrollView
children:
1) LinearLayout
populated with TextViews
2) WebView
3) LinearLayout
populated with RecyclerViews
.
I know about possible issues with RecyclerView
and Behaviours inside of CoordinatorLayout
, but it's not related.
So please don't mention any
recyclerView.getLayoutManager().setAutoMeasureEnabled(true);
recyclerView.setNestedScrollingEnabled(false);
or things like that.
Code sample:
<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>
Upvotes: 18
Views: 2669
Reputation: 43
according to Animating a Scroll Gesture training guide, while overriding computeScroll(), after using mScroller.computeScrollOffset() to calculate proper offset to scroll view, we need use:
ViewCompat.postInvalidateOnAnimation(this);
to animate next scroll. However, in the NestedScrollView, the computeScroll() looks like this:
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
...
}
}
It doesn't request next scroll animation! Which means that after using mScroller.fling(...), the computeScroll() method will sometimes only get called one time, and view doesn't keep fling.
To fix this problem, I have tried to replace the computeScroll in this way:
public void computeScroll(){
if(mScroller.computeScrollOffset()){
...
ViewCompat.postInvalidateOnAnimation(this);
}
}
It may not sound a good solution, but it just works fine for now.
Recent version of NestedScrollView has added the ViewCompat.postInvalidateOnAnimation(this).
Upvotes: 0
Reputation: 1595
So it's clearly a bug in NestedScrollView. I have made a workaround for this, but still waiting for a proper fix from Google side.
https://github.com/Dimezis/FlingableNestedScrollView/
Edit:
Looks like the issue is fixed in support lib 26.0.0-beta2
https://chris.banes.me/2017/06/09/carry-on-scrolling/
Edit 2: Although the scrolling works fine now, in my app I can constantly reproduce this bug:
https://issuetracker.google.com/issues/37051723
If someone encounters it as well, you can find a workaround in a thread mentioned.
Upvotes: 7