Can I have onScrollListener for a ScrollView? Can I have onScrollListener for a ScrollView? android android

Can I have onScrollListener for a ScrollView?


Every instance of View calls getViewTreeObserver(). Now when holding an instance of ViewTreeObserver, you can add an OnScrollChangedListener() to it using the method addOnScrollChangedListener().

You can see more information about this class here.

It lets you be aware of every scrolling event - but without the coordinates. You can get them by using getScrollY() or getScrollX() from within the listener though.

scrollView.getViewTreeObserver().addOnScrollChangedListener(new OnScrollChangedListener() {    @Override    public void onScrollChanged() {        int scrollY = rootScrollView.getScrollY(); // For ScrollView        int scrollX = rootScrollView.getScrollX(); // For HorizontalScrollView        // DO SOMETHING WITH THE SCROLL COORDINATES    }});


This might be very useful.Use NestedScrollView instead of ScrollView. Support Library 23.1 introduced an OnScrollChangeListener to NestedScrollView.So you can do something like this.

 myScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {        @Override        public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {            Log.d("ScrollView","scrollX_"+scrollX+"_scrollY_"+scrollY+"_oldScrollX_"+oldScrollX+"_oldScrollY_"+oldScrollY);            //Do something        }    });


Here's a derived HorizontalScrollView I wrote to handle notifications about scrolling and scroll ending. It properly handles when a user has stopped actively scrolling and when it fully decelerates after a user lets go:

public class ObservableHorizontalScrollView extends HorizontalScrollView {    public interface OnScrollListener {        public void onScrollChanged(ObservableHorizontalScrollView scrollView, int x, int y, int oldX, int oldY);        public void onEndScroll(ObservableHorizontalScrollView scrollView);    }    private boolean mIsScrolling;    private boolean mIsTouching;    private Runnable mScrollingRunnable;    private OnScrollListener mOnScrollListener;    public ObservableHorizontalScrollView(Context context) {        this(context, null, 0);    }    public ObservableHorizontalScrollView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public ObservableHorizontalScrollView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);    }    @Override    public boolean onTouchEvent(MotionEvent ev) {        int action = ev.getAction();        if (action == MotionEvent.ACTION_MOVE) {            mIsTouching = true;            mIsScrolling = true;        } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {            if (mIsTouching && !mIsScrolling) {                if (mOnScrollListener != null) {                    mOnScrollListener.onEndScroll(this);                }            }            mIsTouching = false;        }        return super.onTouchEvent(ev);    }    @Override    protected void onScrollChanged(int x, int y, int oldX, int oldY) {        super.onScrollChanged(x, y, oldX, oldY);        if (Math.abs(oldX - x) > 0) {            if (mScrollingRunnable != null) {                removeCallbacks(mScrollingRunnable);            }            mScrollingRunnable = new Runnable() {                public void run() {                    if (mIsScrolling && !mIsTouching) {                        if (mOnScrollListener != null) {                            mOnScrollListener.onEndScroll(ObservableHorizontalScrollView.this);                        }                    }                    mIsScrolling = false;                    mScrollingRunnable = null;                }            };            postDelayed(mScrollingRunnable, 200);        }        if (mOnScrollListener != null) {            mOnScrollListener.onScrollChanged(this, x, y, oldX, oldY);        }    }    public OnScrollListener getOnScrollListener() {        return mOnScrollListener;    }    public void setOnScrollListener(OnScrollListener mOnEndScrollListener) {        this.mOnScrollListener = mOnEndScrollListener;    }}