2013-10-02 6 views
7

Я переопределил ScrollView, чтобы пройти MotionEvent s до GestureDetector, чтобы обнаружить события перехода на ScrollView. Мне нужно определить, когда прокрутка останавливается. Это не совпадает с событием MotionEvent.ACTION_UP, потому что это обычно происходит в начале жестов fling, за которым следует шквал onScrollChanged() вызовов ScrollView.Обнаружение конца перехода на ScrollView

Поэтому в основном то, что мы имеем дело с здесь следующие события:

  1. onFling
  2. onScrollChanged, onScrollChanged, onScrollChanged, ..., onScrollChanged

Там нет обратного вызова для того, когда События onScrollChanged завершаются стрельбой. Я думал отправить сообщение в очередь событий, используя Handler во время onFling и ожидая выполнения Runnable, чтобы сигнализировать о завершении перехода, к сожалению, он срабатывает после первого вызова onScrollChanged.

Любые другие идеи?

+0

Да, как я упоминал в своем вопросе, что подход не работает. –

+0

Вы видели/пытались ответить? –

ответ

15

Я собрал несколько ответов от here, чтобы построить рабочий слушатель, похожий на способ AbsListView. Это, по сути, то, что вы описываете, и это хорошо работает в моем тестировании.

Примечание: вы можете просто переопределить ScrollView.fling(int velocityY), а не использовать свой собственный GestureDetector.

import android.content.Context; 
import android.util.AttributeSet; 
import android.widget.ScrollView; 

public class CustomScrollView extends ScrollView { 

    private static final int DELAY_MILLIS = 100; 

    public interface OnFlingListener { 
     public void onFlingStarted(); 
     public void onFlingStopped(); 
    } 

    private OnFlingListener mFlingListener; 
    private Runnable mScrollChecker; 
    private int mPreviousPosition; 

    public CustomScrollView(Context context) { 
     this(context, null, 0); 
    } 

    public CustomScrollView(Context context, AttributeSet attrs) { 
     this(context, attrs, 0); 
    } 

    public CustomScrollView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 

     mScrollChecker = new Runnable() { 
      @Override 
      public void run() { 
       int position = getScrollY(); 
       if (mPreviousPosition - position == 0) { 
        mFlingListener.onFlingStopped(); 
        removeCallbacks(mScrollChecker); 
       } else { 
        mPreviousPosition = getScrollY(); 
        postDelayed(mScrollChecker, DELAY_MILLIS); 
       } 
      } 
     }; 
    } 

    @Override 
    public void fling(int velocityY) { 
     super.fling(velocityY); 

     if (mFlingListener != null) { 
      mFlingListener.onFlingStarted(); 
      post(mScrollChecker); 
     } 
    } 

    public OnFlingListener getOnFlingListener() { 
     return mFlingListener; 
    } 

    public void setOnFlingListener(OnFlingListener mOnFlingListener) { 
     this.mFlingListener = mOnFlingListener; 
    } 

} 
+0

Я не пробовал это, но постоянные сообщения в потоке пользовательского интерфейса могут быть проблемой производительности? –

+1

Учитывая, что это похоже на то, как это делается с помощью 'Scroller' в' AbsListView', я думаю, с вами все будет в порядке. Они фактически обновляют каждые 40 мс. Проверьте «AbsListView.FlingRunnable» –

Смежные вопросы