Android: onScrollStateChanged SCROLL_STATE_IDLE иногда не срабатывает

У меня проблема. Что я делаю: у меня есть ListView, в котором есть некоторые изображения. Чтобы сделать прокрутку более гладкой, я отключил отображение изображений при прокрутке. Теперь в Android появляется ошибка которая иногда заставляет состояние прокрутки не возвращаться из SCROLL_STATE_FLING обратно в SCROLL_STATE_IDLE, что приводит к тому, что мои изображения не появляется снова.

Моя первая мысль состояла в том, чтобы установить onTouchListener и проверить, когда я получаю ACTION_UP, но это не помогает, потому что состояние SCROLL_STATE_FLING, очевидно, устанавливается после этого. Поэтому теперь я подумал, что могу запустить таймер, когда состояние SCROLL_STATE_FLING устанавливается и проверяется через некоторое время, если состояние все еще находится в режиме ожидания, а затем аннулирует мое представление. Но я не думаю, что это очень хорошее решение.

Есть ли у кого-нибудь лучшее представление о том, как я могу это сделать? Я видел этот ответ, но мне нужно решение для уровня API < 9 (плюс это также иногда случается, когда он не перекрещивается)

Вот мой код для этого:

    mList.setOnScrollListener(new OnScrollListener() {

        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            mListAdapter.setIsScrolling(scrollState != SCROLL_STATE_IDLE);
            Log.i(this, "scrollStateChanged" + scrollState);
            if (scrollState == SCROLL_STATE_IDLE) {
                mList.invalidateViews();
            }
        }

        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        }
    });

Спасибо, Мария

Ответ 1

У меня была та же проблема, поэтому я решил просто определить, достигло ли положение прокрутки последней страницы и в этом случае всегда загружать изображения независимо от состояния прокрутки (поскольку проблема, похоже, всегда возникает, когда пользователь бросает до конца списка). Таким образом, вы изменили бы свой код:

mList.setOnScrollListener(new OnScrollListener() {

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        mListAdapter.setIsScrolling(scrollState != SCROLL_STATE_IDLE);
        Log.i(this, "scrollStateChanged" + scrollState);

        int first = view.getFirstVisiblePosition();
        int count = view.getChildCount();

        if (scrollState == SCROLL_STATE_IDLE || (first + count > mListAdapter.getCount()) ) {
            mList.invalidateViews();
        }
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    }
});

Ответ 2

У меня была такая же проблема, и был найден обходной путь в списке ошибок:

Для любого, кто все еще сталкивается с этой проблемой (как я был на прошлой неделе), обходной путь, который работает для меня, следующий: if android SDKInt == 7 установите onTouchListener на (Abs)ListView

В этом onTouchListener, когда действие события OnTouch MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL вы силой a onScrollStateChanged с первым a SCROLL_STATE_FLING, а затем a SCROLL_STATE_IDLE

Пример кода: в onCreate:

  if(androidSDKInt <= 7){
      listViewDateSelector.setOnTouchListener(new FingerTracker(onScrollListener));       }

Затем добавьте частный класс с помощью:

  private class FingerTracker implements View.OnTouchListener {
      private OnScrollListener myOnScrollListener;

      public FingerTracker(OnScrollListener onScrollListener){
          myOnScrollListener = onScrollListener;          }

      public boolean onTouch(View view, MotionEvent event) {
          final int action = event.getAction();
          boolean mFingerUp = action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL;
          if (mFingerUp) {
              myOnScrollListener.onScrollStateChanged((AbsListView) view, OnScrollListener.SCROLL_STATE_FLING);
              myOnScrollListener.onScrollStateChanged((AbsListView) view, OnScrollListener.SCROLL_STATE_IDLE);
          }
          return false;           }       }

Ответ 3

переопределить LinearSnapHelper findSnapView