Detect end of ScrollView Detect end of ScrollView android android

Detect end of ScrollView


Did it!

Aside of the fix Alexandre kindly provide me, I had to create an Interface:

public interface ScrollViewListener {    void onScrollChanged(ScrollViewExt scrollView,                          int x, int y, int oldx, int oldy);}

Then, i had to override the OnScrollChanged method from ScrollView in my ScrollViewExt:

public class ScrollViewExt extends ScrollView {    private ScrollViewListener scrollViewListener = null;    public ScrollViewExt(Context context) {        super(context);    }    public ScrollViewExt(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);    }    public ScrollViewExt(Context context, AttributeSet attrs) {        super(context, attrs);    }    public void setScrollViewListener(ScrollViewListener scrollViewListener) {        this.scrollViewListener = scrollViewListener;    }    @Override    protected void onScrollChanged(int l, int t, int oldl, int oldt) {        super.onScrollChanged(l, t, oldl, oldt);        if (scrollViewListener != null) {            scrollViewListener.onScrollChanged(this, l, t, oldl, oldt);        }    }}

Now, as Alexandre said, put the package name in the XML tag (my fault), make my Activity class implement the interface created before, and then, put it all together:

scroll = (ScrollViewExt) findViewById(R.id.scrollView1);scroll.setScrollViewListener(this);

And in the method OnScrollChanged, from the interface...

@Overridepublic void onScrollChanged(ScrollViewExt scrollView, int x, int y, int oldx, int oldy) {    // We take the last son in the scrollview    View view = (View) scrollView.getChildAt(scrollView.getChildCount() - 1);    int diff = (view.getBottom() - (scrollView.getHeight() + scrollView.getScrollY()));    // if diff is zero, then the bottom has been reached    if (diff == 0) {        // do stuff    }}

And it worked!

Thank you very much for your help, Alexandre!


I found a simple way to detect this :

   scrollView.getViewTreeObserver()       .addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {            @Override            public void onScrollChanged() {                if (scrollView.getChildAt(0).getBottom()                     <= (scrollView.getHeight() + scrollView.getScrollY())) {                    //scroll view is at bottom                } else {                    //scroll view is not at bottom                }            }        });
  • Doesn't need to custom ScrollView.
  • Scrollview can host only one direct child, so scrollView.getChildAt(0) is okay.
  • This solution is right even the height of direct child of scroll view is match_parent or wrap_content.


All of these answers are so complicated, but there is a simple built-in method that accomplishes this: canScrollVertically(int)

For example:

@Overridepublic void onScrollChanged() {    if (!scrollView.canScrollVertically(1)) {        // bottom of scroll view    }    if (!scrollView.canScrollVertically(-1)) {        // top of scroll view    }}

This also works with RecyclerView, ListView, and actually any other view since the method is implemented on View.

If you have a horizontal ScrollView, the same can be achieved with canScrollHorizontally(int)