Allan Jiang
Allan Jiang

Reputation: 11331

Detect the ListView scroll direction and distance

Is there a way to get a listview's scroll distance, and exactly how far in pixel it scrolls?

Thank you

Upvotes: 1

Views: 3574

Answers (2)

mariotaku
mariotaku

Reputation: 693

See this snippet written by me. It can calculate how far in pixel it scrolls, and listen scroll change.

/**
 * Created by mariotaku on 14/10/22.
 */
public class ListScrollDistanceCalculator implements OnScrollListener {

    private ScrollDistanceListener mScrollDistanceListener;

    private boolean mListScrollStarted;
    private int mFirstVisibleItem;
    private int mFirstVisibleHeight;
    private int mFirstVisibleTop, mFirstVisibleBottom;
    private int mTotalScrollDistance;

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        if (view.getCount() == 0) return;
        switch (scrollState) {
            case SCROLL_STATE_IDLE: {
                mListScrollStarted = false;
                break;
            }
            case SCROLL_STATE_TOUCH_SCROLL: {
                final View firstChild = view.getChildAt(0);
                mFirstVisibleItem = view.getFirstVisiblePosition();
                mFirstVisibleTop = firstChild.getTop();
                mFirstVisibleBottom = firstChild.getBottom();
                mFirstVisibleHeight = firstChild.getHeight();
                mListScrollStarted = true;
                mTotalScrollDistance = 0;
                break;
            }
        }
    }

    public int getTotalScrollDistance() {
        return mTotalScrollDistance;
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        if (totalItemCount == 0 || !mListScrollStarted) return;
        final View firstChild = view.getChildAt(0);
        final int firstVisibleTop = firstChild.getTop(), firstVisibleBottom = firstChild.getBottom();
        final int firstVisibleHeight = firstChild.getHeight();
        final int delta;
        if (firstVisibleItem > mFirstVisibleItem) {
            mFirstVisibleTop += mFirstVisibleHeight;
            delta = firstVisibleTop - mFirstVisibleTop;
        } else if (firstVisibleItem < mFirstVisibleItem) {
            mFirstVisibleBottom -= mFirstVisibleHeight;
            delta = firstVisibleBottom - mFirstVisibleBottom;
        } else {
            delta = firstVisibleBottom - mFirstVisibleBottom;
        }
        mTotalScrollDistance += delta;
        if (mScrollDistanceListener != null) {
            mScrollDistanceListener.onScrollDistanceChanged(delta, mTotalScrollDistance);
        }
        mFirstVisibleTop = firstVisibleTop;
        mFirstVisibleBottom = firstVisibleBottom;
        mFirstVisibleHeight = firstVisibleHeight;
        mFirstVisibleItem = firstVisibleItem;
    }

    public void setScrollDistanceListener(ScrollDistanceListener listener) {
        mScrollDistanceListener = listener;
    }

    public static interface ScrollDistanceListener {
        void onScrollDistanceChanged(int delta, int total);
    }
}

Upvotes: 4

sdabet
sdabet

Reputation: 18670

I think that getScrollY() may help you:

Return the scrolled top position of this view. This is the top edge of the displayed part of your view.

See http://developer.android.com/reference/android/view/View.html#getScrollY()

Upvotes: 0

Related Questions