Исправлена ошибка остановки NestedScrollView для Nougat (API 25)
У меня странная проблема с запуском NestedScrollView на Nexus 5x (7.1.2) и Google Pixel (7.1.1). В других версиях ОС он работает нормально.
Флинковая анимация иногда останавливается сразу после поднятия пальца. Он держится, а следующие несколько выстрелов также могут остановиться.
Чтобы воспроизвести его, вам нужно бросить несколько раз вверх и вниз.
В журналах эти выбросы выглядят почти одинаково с точки зрения скорости, направления и т.д., поэтому я не могу найти настоящую причину этой ошибки.
Также NestedScrollView
не обязательно должен находиться внутри CoordinatorLayout
, он также может иметь не NestedScrollingChild
вообще.
Например, эта ошибка воспроизводится с одним из следующих NestedScrollView
детей:
1) LinearLayout
, заполненном TextViews
2) WebView
3) LinearLayout
, заполненном RecyclerViews
.
Я знаю о возможных проблемах с RecyclerView
и Behaviors внутри CoordinatorLayout
, но это не связано.
Поэтому, пожалуйста, не упоминайте никаких
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
Значит, это ошибка в NestedScrollView.
Я сделал обходной путь для этого, но все еще ожидаю, что исправление будет исправлено со стороны Google.
https://github.com/Dimezis/FlingableNestedScrollView/
Edit
Похоже, проблема исправлена в версии lib 26.0.0-beta2
https://chris.banes.me/2017/06/09/carry-on-scrolling/
Изменить 2:
Хотя прокрутка работает отлично сейчас, в моем приложении я могу постоянно воспроизводить эту ошибку:
https://issuetracker.google.com/issues/37051723
Если кто-то встретит это также, вы можете найти обходной путь в упомянутом потоке.
Ответ 2
в соответствии с Анимация руководства по стилю прокрутки, при переопределении computeScroll(), после использования mScroller.computeScrollOffset() для вычисления правильного смещения прокрутки, нам нужно использовать:
ViewCompat.postInvalidateOnAnimation(this);
для анимации следующего прокрутки.
Однако в NestedScrollView computeScroll() выглядит так:
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
...
}
}
Он не запрашивает следующую анимацию прокрутки! Это означает, что после использования mScroller.fling(...) метод computeScroll() иногда будет вызван только один раз, а просмотр не будет выполняться.
Чтобы устранить эту проблему, я попытался заменить computeScroll таким образом:
public void computeScroll(){
if(mScroller.computeScrollOffset()){
...
ViewCompat.postInvalidateOnAnimation(this);
}
}
Это может показаться неплохим решением, но сейчас оно отлично работает.
Последняя версия NestedScrollView добавила ViewCompat.postInvalidateOnAnimation(this).