Android scrollview на ScrollChanged
У меня есть фиксированный контент в моем текстовом представлении в представлении прокрутки. Когда пользователь прокручивает до определенной позиции, я хотел бы начать действие или вызвать 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
чтобы узнать положение вида прокрутки.
Я нашел этот ответ, есть ли более простое решение, чем объявление интерфейса, просмотр прокрутки и т. Д., Как видно по ссылке, которую я разместил?
10 ответов
Нет.
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.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;
}
});
Я расширил свой 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);
}
}
Вы можете использовать этот триггер, чтобы показать тост или начать активность
scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
@Override
public void onScrollChanged() {
// do something when Scroll
}
});
NestedScrollView аналогичен android.widget.ScrollView, но он поддерживает функции как вложенного прокручивающегося родителя, так и потомка в новых и старых версиях Android.
1-й - использовать привязку NestedScrollView вместо ScrollView
2-й - Установите прослушиватель Scroll, как это, для определения оси 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);
}
}
});
Есть готовый к использованию компонент, который помогает прослушивать события прокрутки произвольных просмотров в Android. Внутренне этот компонент добавляет прослушиватель событий прокрутки ViewTreeObserver на устройствах со старым Android API (аналогично предложенному в ответе Шубхэдипа Чаудхури) и Прослушиватель событий прокрутки View на устройствах с новым Android API (уровень API 23+).
Просто используйте NestedScroll
а также NestedScroll.setOnScrollChangeListener()
,
Начиная с 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
}
});