この振る舞いを下げるのは難しいので、完璧にするのにかなりの時間がかかりました。問題の核心は、私が知る限り、スクロールリスナーだけでは「スクロールストップ」(方向ボタン/トラックボールを含む)を検出するのに十分ではないということです。期待どおりに機能することを組み合わせて実行することになりました。
私ができると思った最善の方法は、ListViewを拡張し、いくつかのメソッドをオーバーライドすることでした。
....
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN || keyCode == KeyEvent.KEYCODE_DPAD_UP) {
startWait();
}
return super.onKeyUp(keyCode, event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
stopWait();
}
if (event.getAction() == MotionEvent.ACTION_UP ||
event.getAction() == MotionEvent.ACTION_CANCEL) {
startWait();
}
return super.onTouchEvent(event);
}
private OnScrollListener customScrollListener = new OnScrollListener() {
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
int totalItemCount) {
stopWait();
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
startWait();
} else {
stopWait();
}
}
};
//All this waiting could be improved, but that's the idea
private Thread waitThread = null;
private int waitCount = Integer.MIN_VALUE;
public void stopWait() {
waitCount = Integer.MIN_VALUE;
}
public synchronized void startWait() {
waitCount = 0;
if (waitThread != null) {
return;
}
waitThread = new Thread(new Runnable() {
@Override
public void run() {
try {
for (; waitCount.get() < 10; waitCount++) {
Thread.sleep(50);
}
//Kick it back to the UI thread.
view.post(theRunnableWithYourOnScrollStopCode); // HERE IS WHERE YOU DO WHATEVER YOU WANTED TO DO ON STOP
} catch (InterruptedException e) {
} finally {
waitThread = null;
}
}
});
waitThread.start();
}
customScrollListener
コンストラクターでもバインドする必要があることに注意してください。この実装は、「イベント」をすぐには発生させないため、実際にスクロールが完全に停止するまで少し待機するので、便利だと思います。