Android scrollview onScrollChanged
Solution 1
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.
Solution 2
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;
}
});
Solution 3
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.
Solution 4
Actually there is a way to know how far the user has scrolled. The method getScrollY() from ScrollView tells you that.
Solution 5
you can use this code to detect is up or down scroll
scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
int lastScroll=0;
@Override
public void onScrollChanged() {
int scrollY = scrollView.getScrollY(); // For ScrollView herzontial use getScrollX()
if (scrollY > lastScroll ) {
Log.e("scroll","down scroll"+scrollY);
} else if (scrollY < lastScroll ) {
Log.e("scroll","up scroll"+scrollY);
}
lastScroll=scrollY;
}
});
Related videos on Youtube
Comments
-
SteD almost 2 years
I have a fixed content in my text view inside a scroll view. When the user scrolls to a certain position, I would like to start an activity or trigger a
Toast
.<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/scroller"> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:layout_width="fill_parent" android:id="@+id/story" android:layout_height="wrap_content" android:text="@string/lorem" android:gravity="fill" /> </LinearLayout> </ScrollView>
My problem is in implementing the protected method
onScrollChanged
to find out the position of the scroll view.I have found this answer, is there an easier solution to this rather than declaring an interface, over ride the scrollview etc as seen on the link I posted?
-
Satria Akbar almost 11 yearsyou can use this stackoverflow.com/questions/10316743/detect-end-of-scrollview
-
-
Timmmm over 11 yearsNope, according to this: stackoverflow.com/questions/2132370/…
-
tulio84z over 11 yearsI used this solution in a project in my company. I test everything before i post something here. Maybe you should do the same?
-
Timmmm over 11 yearsSorry, misread the question. It works for a
ScrollView
but not aListView
or aGridView
. -
Admin over 11 yearsThere is a method onScrollChanged that can be overridden. Likelwise getScrollX, getScrollY can be used.
-
Christopher Perry over 10 yearsThat's not necessarily easier than subclassing
ScrollView
. It's actually more code. If you subclass you can just override theonScrollChanged
method. -
RandomEngy about 10 yearsI tried this and it seems to fire the event 20 times or more for the same scroll Y value. It doesn't seem ideal.
-
Bartek Lipinski over 9 yearsWell... there is a huge problem with this code! And this issue is resulting in errors like the one from @RandomEngy comment. Therefore I don't know why it got upvoted so high. It adds this listener ON EVERY TOUCH EVENT ON SCROLL. So basically if you click your scroll 20 times it will result in 20 calls to listener. The Listener should just be added once. For example like this:
scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() { @Override public void onScrollChanged() { //do stuff }});
. NOT INSIDE ON TOUCH METHOD -
Bartek Lipinski over 9 yearsor even worse it will probably add AT LEAST 40 listeners (at least TOUCH_DOWN and TOUCH_UP for every click) in the example.
-
timemanx over 9 yearsI had
OnTouchListener
because the documentation says "The returned ViewTreeObserver observer is not guaranteed to remain valid for the lifetime of this View". I've edited the answer so that if theViewTreeObserver
isn't alive anymore, the callback to it is removed and added toView
's currentViewtreeObserver
. -
Gabor Peto almost 8 yearsI would suggest subclassing. That is less code and more reusable and avoids the above mentioned issues..
-
dephinera over 7 yearsthere is no backward compatibility tho
-
Lovis over 7 years@define well, there is
NestedScrollView
in the Support lib, you csn use that insead of the regularScrollview
without problems -
dephinera over 7 yearsSorry, for some reason I missed the part where you mention it.. Thanks anyway
-
Lovis over 7 years@define I simply didn't mention that you can use the NestedScrollView instead of the normal one. I'll add it to the answer.
-
the_dude_abides almost 7 yearsThis is great. We support API 18+ and I really wanted this stock functionality. Thanks!
-
Chanaka Fernando over 6 yearsSeems this answer is invalid now. Starting from API 23 (M) there is a listener called "OnScrollChangeListener" scrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() { @Override public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) { //work with parameters } });
-
Benjamin Basmaci almost 5 years@S.D.NChanakaFernando It should also be noted that it still does not give a built in solution for specifics when it comes to scrolling. For example, if you want to detect the end of a scroll, you will have to do that manually using
onScrollChangeListener
, which is super annoying. Here are some suggestions of anybody stumbles over this problem: stackoverflow.com/questions/8181828/…