2010-11-24 2 views
22

У меня есть фиксированный контент в моем текстовом представлении внутри прокрутки. Когда пользователь прокручивается до определенной позиции, я хотел бы начать действие или вызвать Toast.Android scrollview onScrollChanged

<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 выяснить позицию зрения прокрутки.

Я нашел this Ответ: есть ли более легкое решение для этого, вместо того чтобы объявлять интерфейс, перемещаться по экрану прокрутки и т. Д., Как видно по ссылке, которую я разместил?

+1

вы можете использовать этот Http: // stackoverflow.com/questions/10316743/detect-end-of-scrollview –

ответ

11

No.

ScrollView не обеспечивает слушателя для события прокрутки или даже способ проверить, насколько далеко вниз пользователь прокрутил, так что вы должны делать то, что предлагается по ссылке.

+13

Существует метод onScrollChanged, который можно переопределить. Посколь- ку getScrollX можно использовать getScrollY. –

+0

Кажется, этот ответ сейчас недействителен. Начиная с API 23 (M) появляется слушатель, называемый «OnScrollChangeListener» scrollView.setOnScrollChangeListener (новый View.OnScrollChangeListener() { @Override public void onScrollChange (просмотр v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) { // работа с параметрами } }); –

8

На самом деле существует способ узнать, как далеко прокручивается пользователь. Метод getScrollY() из ScrollView сообщает об этом.

+0

Нет, в соответствии с этим: http://stackoverflow.com/questions/2132370/android-listview-getscrolly-does-it-work – Timmmm

+3

Я использовал это решение в проекте в своей компании. Я проверяю все, прежде чем я что-то отправлю. Может быть, вы должны сделать то же самое? – tulio84z

+0

Извините, неверно сформулировал вопрос. Он работает для 'ScrollView', но не' ListView' или 'GridView'. – Timmmm

47

Существует намного более простой способ, чем подклассификация ScrollView. Объект ViewTreeObserverScrollView может использоваться для прослушивания свитков.

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; 
    } 
}); 
+1

Это не обязательно проще, чем подклассификация 'ScrollView'. На самом деле это больше кода. Если вы используете подкласс, вы можете просто переопределить метод onScrollChanged. –

+1

Я пробовал это, и он, похоже, запускает событие 20 раз или более для того же значения прокрутки Y. Это не кажется идеальным. – RandomEngy

+0

Ну ... есть огромная проблема с этим кодом! И эта проблема приводит к ошибкам, подобным тому, что из комментария @RandomEngy. Поэтому я не знаю, почему он так высоко поднялся. Он добавляет этого слушателя в КАЖДОЕ СКАЧАТЬ СОБЫТИЕ НА ПРОКРУТКЕ. Таким образом, в основном, если вы нажмете свой свиток 20 раз, это приведет к 20 вызовам слушателя. Слушатель следует просто добавить один раз. Например, вот так: 'scrollView.getViewTreeObserver(). AddOnScrollChangedListener (новый ViewTreeObserver.OnScrollChangedListener() { @Override public void onScrollChanged() {// do stuff}});'. NOT INSIDE ON TOUCH METHOD –

9

Этот вопрос довольно старый, но в случае, если кто-то падает (как я):

Начиная с API 23, андроид View имеет OnScrollChangeListener и matching setter.

NestedScrollView из библиотеки поддержки также поддерживает настройку прослушивания прокрутки еще до этого уровня API. Насколько я знаю, NestedScrollView может быть использован в качестве замены для обычного ScrollView без проблем.

+0

нет обратной совместимости tho – definera

+0

@define хорошо, есть 'NestedScrollView' в библиотеке поддержки, вы csn используете это insead регулярного' Scrollview' без проблем – Lovis

+0

Извините, по какой-то причине я пропустил ту часть, где вы упомянули об этом .. Спасибо в любом случае – definera

2

Я продлил свой scrollView. This link может помочь.

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); 
    } 
} 
0

Просто используйте NestedScroll и NestedScroll.setOnScrollChangeListener().

0

ready for use component, который помогает прослушивать события прокрутки произвольных просмотров в Android. Внутренне этот компонент добавляет прослушиватель событий прокрутки ViewTreeObserver ViewTreeObserver на устройствах со старым API Android (аналогично предложению в ответе Шубхадепа Чаудхури) и прослушивает просмотр прокрутки событий на устройствах с новым API Android (уровень API 23+).

0

Начиная с 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 
     } 
    }); 
1

NestedScrollView просто как android.widget.ScrollView, но он поддерживает действующий и как вложенной прокруткой родителя и ребенка на новых и старых версиях Android.

первый - Использование NestedScrollView связывания вместо Scrollview

второй - спирального слушатель, как это, чтобы обнаружить ось 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); 
      } 
     } 
    }); 
Смежные вопросы