Android scrollview onScrollChanged

泪湿孤枕 提交于 2019-11-28 06:51:30

No.

ScrollView doesn't provide a listener for scroll events or even a way to check how far down the user has scrolled, so you have to do what is suggested by the link.

There is a much easier way than subclassing the ScrollView. The ViewTreeObserver object of the ScrollView can be used to listen for scrolls.

Since the ViewTreeObserver object might change during the lifetime of the ScrollView, we need to register an OnTouchListener on the ScrollView to get it's ViewTreeObserver at the time of scroll.

final ViewTreeObserver.OnScrollChangedListener onScrollChangedListener = new
                           ViewTreeObserver.OnScrollChangedListener() {

    @Override
    public void onScrollChanged() {
        //do stuff here 
    }
};

final ScrollView scrollView = (ScrollView) findViewById(R.id.scroller);
scrollView.setOnTouchListener(new View.OnTouchListener() {
    private ViewTreeObserver observer;

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (observer == null) {
            observer = scrollView.getViewTreeObserver();
            observer.addOnScrollChangedListener(onScrollChangedListener);
        }
        else if (!observer.isAlive()) {
            observer.removeOnScrollChangedListener(onScrollChangedListener);
            observer = scrollView.getViewTreeObserver();
            observer.addOnScrollChangedListener(onScrollChangedListener);
        }

        return false;
    }
});

This question is fairly old, but in case somebody drops by (like me):

Starting with API 23, Android's View has a OnScrollChangeListener and the matching setter.

The NestedScrollView from the Support library also supports setting a scroll listener even before that API level. As far as I know, NestedScrollView can be used as a replacement for the normal ScrollView without any problems.

Actually there is a way to know how far the user has scrolled. The method getScrollY() from ScrollView tells you that.

I extended my scrollView. This link may help.

class MyScroll extends ScrollView {
    boolean onTop=true;
    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        //Log.d(TAG, "scroll changed: " + this.getTop() + " "+t);
        if(t <= 0){
            onTop = true;
            //Log.d(TAG, "scroll top: " + t);
            super.onScrollChanged(l, t, oldl, oldt);
            return;
            // reaches the top end
        }
        onTop = false;

        View view = (View) getChildAt(getChildCount()-1);
        int diff = (view.getBottom()-(getHeight()+getScrollY()+view.getTop()));// Calculate the scrolldiff
        if( diff <= 0 ){
            // if diff is zero, then the bottom has been reached
        }
        super.onScrollChanged(l, t, oldl, oldt);
    }
}

NestedScrollView is just like android.widget.ScrollView, but it supports acting as both a nested scrolling parent and child on both new and old versions of Android.

1st - Use NestedScrollView binding instead ScrollView

2nd - Set Scroll listener, like this, to detect axis Y moving for a headerView by example

    nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {

        @Override
        public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
            Log.d(TAG, "onScrollChangeForY - scrollY: " + scrollY + " oldScrollY: " + oldScrollY);

            int MOVE = -1, SCROLL_UP = 0, SCROLL_DOWN = 1;
            float initialPositionY = headerView.getY();

            MOVE = scrollY > oldScrollY ? SCROLL_UP : SCROLL_DOWN;

            if (MOVE == SCROLL_UP) {

                int incrementY = scrollY - oldScrollY;

                headerView.setY(initialPositionY - incrementY);

            } else {

                int incrementY = oldScrollY - scrollY;

                headerView.setY(initialPositionY + incrementY);
            }
        }
    });

There is ready for use component, which helps to listen to scroll events of arbitrary views in Android. Internally this component adds ViewTreeObserver scroll events listener on devices with old Android API (similar as proposed in Shubhadeep Chaudhuri's answer) and View scroll events listener on devices with new Android API (API level 23+).

Kai Wang

Just use NestedScroll and NestedScroll.setOnScrollChangeListener().

Starting from API 23 Android M, you can use OnScrollChangeListener.

 scrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
        @Override
        public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
            //work with parameters
        }
    });

you can use this trigger to show Toast or Start Activity

 scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
        @Override
        public void onScrollChanged() {
             // do something when Scroll  
        }
    });
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!