Android – дубликаты событий ListView

В моем приложении у меня есть ListView, поддерживаемый ArrayAdapter. В нем я обнаруживаю события в методе OnScrollListener # onScroll, чтобы найти конец списка. Я заметил, что по телефону (MyTouch) и трек-мяч, и жест / сенсорная прокрутка вызовут событие дважды. На эмуляторе я получаю такое же поведение с помощью прокручивающего колеса и прокрутки кликов и наркотиков. Однако в эмуляторе, если я использую кнопку со стрелкой вниз для прокрутки, событие запускается только один раз.

Вот код:

this.view.setOnScrollListener(new OnScrollListener() { @Override public void onScroll(final AbsListView view, final int first, final int visible, final int total) { // detect if last item is visible if (visible < total && (first + visible == total)) { Log.d("OnScrollListener - end of list", "fvi: " + first + ", vic: " + visible + ", tic: " + total); // this line gets called twice onLastListItemDisplayed(total, visible); } } } 

Как подавить или обработать это поведение? Мне нужно только одно событие и пытаться не возвращаться к таким глупым хакам, как логическое поле.

Насколько я могу судить – оба события имеют одинаковый стек

 Thread [<3> main] (Suspended (breakpoint at line 116 in SearchResultsView$4)) SearchResultsView$4.onScroll(AbsListView, int, int, int) line: 116 ListView(AbsListView).invokeOnItemScrollListener() line: 655 ListView.arrowScrollImpl(int) line: 2256 ListView.arrowScroll(int) line: 2172 ListView.commonKey(int, int, KeyEvent) line: 1977 ListView.onKeyMultiple(int, int, KeyEvent) line: 1929 KeyEvent.dispatch(KeyEvent$Callback) line: 899 ListView(View).dispatchKeyEvent(KeyEvent) line: 3647 ListView(ViewGroup).dispatchKeyEvent(KeyEvent) line: 744 ListView.dispatchKeyEvent(KeyEvent) line: 1909 FrameLayout(ViewGroup).dispatchKeyEvent(KeyEvent) line: 746 LinearLayout(ViewGroup).dispatchKeyEvent(KeyEvent) line: 746 PhoneWindow$DecorView(ViewGroup).dispatchKeyEvent(KeyEvent) line: 746 PhoneWindow$DecorView.superDispatchKeyEvent(KeyEvent) line: 1708 PhoneWindow.superDispatchKeyEvent(KeyEvent) line: 1197 SearchResultsView(Activity).dispatchKeyEvent(KeyEvent) line: 1967 PhoneWindow$DecorView.dispatchKeyEvent(KeyEvent) line: 1684 ViewRoot.deliverKeyEventToViewHierarchy(KeyEvent, boolean) line: 2329 ViewRoot.handleFinishedEvent(int, boolean) line: 2299 ViewRoot.handleMessage(Message) line: 1621 ViewRoot(Handler).dispatchMessage(Message) line: 99 Looper.loop() line: 123 ActivityThread.main(String[]) line: 4203 Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method] Method.invoke(Object, Object...) line: 521 ZygoteInit$MethodAndArgsCaller.run() line: 791 ZygoteInit.main(String[]) line: 549 NativeStart.main(String[]) line: not available [native method] 

Создана ошибка PS

PPS И закрыт очень полезным ответом The trackball and the touch screen send several motion events very rapidly. This behavior is expected. The trackball and the touch screen send several motion events very rapidly. This behavior is expected.

Поскольку хорошие люди Google говорят, что это так же, as intended , является уродливым жестоким способом справиться с этой проблемой, которая работает на меня. В основном предположение заключается в том, что по мере выпуска событий я сравниваю последний сохраненный индекс первого элемента с тем, который передается в вызове onScroll . Я обработаю событие только в том случае, если они не совпадают:

  this.view.setOnScrollListener(new OnScrollListener() { private int lastSavedFirst = -1; @Override public void onScroll(final AbsListView view, final int first, final int visible, final int total) { // detect if last item is visible if (visible < total && (first + visible == total)) { // only process first event if (first != lastSavedFirst) { lastSavedFirst = first; Log.d("OnScrollListener - end of list", "fvi: " + first + ", vic: " + visible + ", tic: " + total); onLastListItemDisplayed(total, visible); } } } @Override public void onScrollStateChanged(final AbsListView view, final int scrollState) { // Log.d("OnScrollListener", "state: " + scrollState); } }); 

У меня также есть эта проблема с несколькими событиями, когда я прокручивал ListView. Я намеревался загрузить больше ListItems в тот момент, когда я передавал стоимость трески. Тем не менее, это всегда приводило к множественным вызовам AsyncTasks, которые заполняли мой ListView быстрее, чем хотелось.

Я нашел хорошее решение в этом блоге . Это в основном включает проверку булевых, хотя вам не нравится это решение. Я считаю, что это тоже хакки, но я не придумал другого решения.