Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NestedScrollView's fullScroll(View.FOCUS_UP) not working properly

I have a NestedScrollView populated with a vertical LinearLayout, which itself has a bunch of children of various view types: multiple TextViews, two static GridViews, and even a FrameLayout to show a Fragment beneath all of this.

When pressing the back button, if the user has scrolled below a certain point, instead of finishing the Activity, the "scrollToTop" method is called:

public static void scrollToTop(final NestedScrollView scrollview) {
    new Handler().postDelayed(new Runnable() {
        public void run() {
            scrollview.fullScroll(NestedScrollView.FOCUS_UP);
        }
    }, 200);
}

This works in the previous version of my app, which is in the Play Store. But now, after updating my app to target Android Oreo (and updating the support library to version 26.0.2), instead of scrolling to the top, it seems to start scrolling from below the NestedScrollView's original scroll position, and stops where it was. So it just appears as a weird stutter. At some positions, however, it does scroll to the top (albeit very rarely and inconsistently), and others it actually scrolls to the bottom, for what reason I don't understand.

I have been experimenting with view focusability, to no avail. For example, I read that the Static GridViews may interrupt focus while scrolling. I've also tried various different methods to scroll up, such as

scrollview.pageScroll(View.FOCUS_UP);

and

scrollview.smoothScrollTo(0,0);

But nothing seems to work. Is there something wrong with the support library this time around?

like image 770
S Fitz Avatar asked Sep 11 '17 13:09

S Fitz


People also ask

What is nested scrolling enabled?

NestedScrollView is just like ScrollView, but it supports acting as both a nested scrolling parent and child on both new and old versions of Android. It is enabled by default. NestedScrollView is used when there is a need for a scrolling view inside another scrolling view.

How do I scroll to top programmatically?

Use the View. scollTo(int x, int y) instead to scroll to the top.


3 Answers

try this

add android:descendantFocusability="blocksDescendants" to the LinearLayout inside NestedScrollView and this also

to scroll to top of NestedScrollView use this

NestedScrollView.scrollTo(0, 0);

Edit

Use fling() and smoothScrollTo togather

nestedScrollView.post(new Runnable() {
   @Override
   public void run() {
      nestedScrollView.fling(0);
      nestedScrollView.smoothScrollTo(0, 0);
   }
});
like image 121
AskNilesh Avatar answered Oct 01 '22 11:10

AskNilesh


This code works for me.

scrollView.post {
    scrollView.fling(0)
    scrollView.fullScroll(ScrollView.FOCUS_UP)
}
like image 37
WuHaojie Avatar answered Oct 01 '22 10:10

WuHaojie


UPDATE:

Found a better solution. Try this combo:

scrollView.fling(0);  // Sets mLastScrollerY for next command
scrollView.smoothScrollTo(0, 0);  // Starts a scroll itself

Looks like a hack, but works well on both my devices (tested with Support Library 26.0.0 & 27.0.2). Can be used to scroll smoothly to any other position. Based on the idea that the problem lies in missing update of mLastScrollerY.

Please leave a feedback if it works for you or not.

Original answer:

Hit this issue too.

NestedScrollView.smoothScrollTo(0, 0) worked in Support Library up to 25.4.0, and doesn't work since 26.0.0 up to current 27.0.2. The contents of NestedScrollView doesn't matter (some TextViews are enough).

This bug is already reported twice on Google Issue Tracker. Minimal project to reproduce it can be found on GitHub.

Found two working solutions:

  1. NestedScrollView.scrollTo(0, 0) (see accepted answer, jumps abruptly)
  2. NestedScrollView.fling(-10000) (scrolls smoothly, but appropriate velocity value depends on current position, device, desired scrolling time and so on)

It was not necessary to change focusability in my case.

like image 44
gmk57 Avatar answered Oct 01 '22 09:10

gmk57