How do I check if NestedScrollView is currently scrolling?

Viewed 465

I have a NestedScrollView and I want to see weather it is scrolling at the moment.

nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
        @Override
        public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {}

    });

I've looked online and couldn't find a solution.

2 Answers

To do this you will have to write your custom view which extend a NestedScrollView and in that view override the onScrollChange() methods and add logs inside that method to get the value of the scroll, you are writing a custom view as you cant add logs to the systems widgets.

Option 1 (With ScrollChangeListener)

One option may be to store and compare scrollY and oldScrollY values within your scrollChangeListener. Something as simple as this might work (though it has not been formally tested):

private boolean scrollHasBeenChecked = false;
    
    nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
        @Override
        public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
            
            
            if(!scrollHasBeenChecked) {

                scrollHasBeenChecked = true;
                int scrollDif = scrollY - oldScrollY;
                
                final Handler handler0 = new Handler(Looper.getMainLooper());
                handler0.postDelayed(new Runnable() {
                    @Override
                    public void run() {

                        if(scrollDif == scrollY - oldScrollY) {
                            
                            //Proceed
                            
                        } else {

                            scrollHasBeenChecked = false;
                            
                        }

                    }
                    //Adjust accordingly
                }, 250);
                
            }
            
        }

    });

Option 2 (Without ScrollChangeListener)

Depending on the context of your situation, you may be able to cross-check scrollY values. In my code, I needed to make my recyclerView visible after a programmatic scroll to the last visible position in my adapter class without overwriting a scrollChangeListener in my main class. If my nestedScrollView.getScrollY() == lastVisiblePosition (check in a delay runnable loop), then it is no longer scrolling*. A general solution based on this concept might work like:

final Handler handler = new Handler(Looper.getMainLooper());
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {

           int y = nestedScrollView.getScrollY();
           
           checkIfStillScrolling(y);

        }
        //Pick an appropriate delay time or replace runnable with some equivalent checking mechanism
    }, 1000);


private void checkIfStillScrolling(final int y) {

    final Handler handler = new Handler(Looper.getMainLooper());
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {

            if(y = nestedScrollView.getScrollY()){

                //Next step goes here

            } else {

                checkIfStillScrolling(y);

            }

        }
        //Pick an appropriate loop delay time
    }, 100);

}

*more or less - have to account for lifecycle, but that isn't relevant to this specifically

Related