Как определить, является ли ListView быстрой прокруткой

Есть ли способ определить, является ли ListView быстрой прокруткой? То есть, можем ли мы как-то узнать, когда пользователь нажимает и отпускает FastScroller?

2 ответа

Отражение позволяет вам сделать это. Если взглянуть на исходный код AbsListView, FastScroller объект, который обозначает оболочку вокруг функции быстрой прокрутки. Его исходный код показывает интересное поле:

/**
 * Current decoration state, one of:
 * <ul>
 * <li>{@link #STATE_NONE}, nothing visible
 * <li>{@link #STATE_VISIBLE}, showing track and thumb
 * <li>{@link #STATE_DRAGGING}, visible and showing preview
 * </ul>
 */
private int mState;

Это поле содержит статус FastScroller объект. Решение состоит в том, чтобы прочитать значение этого поля через отражение, каждый раз, когда onScroll() а также onScrollStateChanged() методы запускаются.

Этот код реализует решение, описанное выше:

private class CustomScrollListener implements OnScrollListener {

    private ListView list;
    private int mState = -1;
    private Field stateField = null;
    private Object mFastScroller;
    private int STATE_DRAGGING;

    public CustomScrollListener() {
        super();

        String fastScrollFieldName = "mFastScroller";
        // this has changed on Lollipop
        if (Build.VERSION.SDK_INT >= 21) {
            fastScrollFieldName = "mFastScroll";
        }

        try {
            Field fastScrollerField = AbsListView.class.getDeclaredField(fastScrollFieldName);
            fastScrollerField.setAccessible(true);
            mFastScroller = fastScrollerField.get(list);

            Field stateDraggingField = mFastScroller.getClass().getDeclaredField("STATE_DRAGGING");
            stateDraggingField.setAccessible(true);
            STATE_DRAGGING = stateDraggingField.getInt(mFastScroller);

            stateField = mFastScroller.getClass().getDeclaredField("mState");
            stateField.setAccessible(true);
            mState = stateField.getInt(mFastScroller);

        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {

        // update fast scroll state
        try {
            if (stateField != null) {
                mState = stateField.getInt(mFastScroller);
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }


        if (mState == STATE_DRAGGING)) {
            // the user is fast scrolling through the list
        }
    }

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

        // update fast scroll state
        try {
            if (stateField != null) {
                mState = stateField.getInt(mFastScroller);
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

    }
}

Попробуйте использовать setOnScrollListener и реализовать onScrollStateChanged. ScrollState может быть в режиме ожидания, сенсорной прокруткой или переключением

setOnScrollListener(new OnScrollListener(){
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
      // TODO Auto-generated method stub
    }
    public void onScrollStateChanged(AbsListView view, int scrollState) {
      // TODO Auto-generated method stub
      if(scrollState == 2) Log.i("a", "fast scroll");
    }
  });
}
Другие вопросы по тегам