Ответ 1
Нет.
ScrollView не предоставляет прослушиватель для событий прокрутки или даже способ проверки того, насколько далеко прокручивается пользователь, поэтому вам нужно сделать то, что предлагается по ссылке.
У меня есть фиксированный контент в моем текстовом представлении внутри прокрутки. Когда пользователь прокручивается до определенной позиции, я хотел бы начать действие или запустить 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>
Моя проблема заключается в реализации защищенного метода onScrollChanged
, чтобы узнать положение прокрутки.
Я нашел этот ответ, есть ли более простое решение для этого, а не объявление интерфейса, а также прокрутка scrollview и т.д., как видно по ссылке, которую я разместил?
Нет.
ScrollView не предоставляет прослушиватель для событий прокрутки или даже способ проверки того, насколько далеко прокручивается пользователь, поэтому вам нужно сделать то, что предлагается по ссылке.
Существует гораздо более простой способ, чем подклассификация ScrollView
. Объект ViewTreeObserver
объекта ScrollView
может использоваться для прослушивания свитков.
Так как объект ViewTreeObserver
может меняться в течение времени жизни ScrollView
, нам нужно зарегистрировать OnTouchListener
на ScrollView
, чтобы получить его ViewTreeObserver
во время прокрутки.
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;
}
});
Этот вопрос довольно старый, но в случае, если кто-то падает (например, я):
Начиная с API 23, у Android View
есть OnScrollChangeListener
и сопоставляющий сеттер.
NestedScrollView из библиотеки поддержки также поддерживает настройку прослушивания прокрутки еще до этого уровня API. Насколько мне известно, NestedScrollView
можно без проблем заменять обычным ScrollView
.
На самом деле есть способ узнать, как далеко прокручивается пользователь. Метод getScrollY() из ScrollView сообщает об этом.
Я расширил свой scrollView. Эта ссылка может помочь.
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 похож на android.widget.ScrollView, но он поддерживает действие как родителя и дочернего родителя с прокруткой на обеих новых и старых версиях Android.
1st - используйте привязку NestedScrollView вместо ScrollView
2nd - установите Scroll listener, как это, для определения оси Y, перемещающейся для headerView на примере
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);
}
}
});
Просто используйте NestedScroll
и NestedScroll.setOnScrollChangeListener()
.
Существует готовый к использованию компонент, который помогает прослушивать прокрутки событий произвольных просмотров в Android. Внутри этого компонента добавляется прослушиватель событий прокрутки ViewTreeObserver ViewTreeObserver на устройствах со старым API Android (аналогично предложению в ответе Shubhadeep Chaudhuri) и View List List на устройствах с новым API Android (API-уровень 23+).
Начиная с API 23 Android M, вы можете использовать OnScrollChangeListener.
scrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
@Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
//work with parameters
}
});
Вы можете использовать этот триггер, чтобы показать тост или начать действие
scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
@Override
public void onScrollChanged() {
// do something when 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;
}
});