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
        }
    });
Другие вопросы по тегам