Обнаружение конца перехода на ScrollView

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

Таким образом, в основном мы имеем дело с следующими событиями:

  1. onFling
  2. OnScrollChanged, onScrollChanged, onScrollChanged, …, onScrollChanged

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

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

Я AbsListView несколько ответов отсюда, чтобы создать рабочий слушатель, похожий на способ 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; } }