Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android ListView current scroll location Y pixels

I'm trying to detect when a list view is scrolled beyond certain fixed threshold in pixels (half way through the first item). Unfortunately listview's getScrollY() seems to always return 0 instad of the scroll position. Is there any way to get the actual scroll location by pixel?

Here's the code I tried to use but as said it only returns 0.

getListView().setOnScrollListener(new AbsListView.OnScrollListener() {
    public void onScroll(AbsListView view, int firstVisibleItem,
                         int visibleItemCount, int totalItemCount) {
        Log.d("scroll", "scroll: " + getListView().getScrollY());
    }

    public void onScrollStateChanged(AbsListView view, int scrollState) {
        if (scrollState == 0)
        Log.d("scroll", "scrolling stopped");
    }
});
like image 462
Juhani Avatar asked Oct 04 '12 12:10

Juhani


3 Answers

There is no notion of Y scroll for a ListView in Android simply because the total height of the content is unknown. Only the height of the displayed content is known.

However it is possible to get the current position/Y scroll of a visible item using the following hack:

getListView().getChildAt(0).getTop();
like image 62
Cyril Mottier Avatar answered Oct 13 '22 23:10

Cyril Mottier


A refactor code of Malachiasz's answer. This function is used for dynamic row's height.

Call onScroll listener

mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {

            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                if (mCardsListView.getChildCount() > 0) {
                    int scrollY = getScrollY();
                }
            }
        });

getScrollY function

private Dictionary<Integer, Integer> mListViewItemHeights = new Hashtable<Integer, Integer>(); 
private int getScrollY() {
        View child = mCardsListView.getChildAt(0); //this is the first visible row
        if (child == null) return 0;

        int scrollY = -child.getTop();

        mListViewItemHeights.put(mCardsListView.getFirstVisiblePosition(), child.getHeight());

        for (int i = 0; i < mCardsListView.getFirstVisiblePosition(); ++i) {
            Integer hei = mListViewItemHeights.get(i);

            //Manual add hei each row into scrollY
            if (hei != null)
                scrollY += hei;
        }

        return scrollY;
    }
like image 2
Tai Le Anh Avatar answered Oct 13 '22 23:10

Tai Le Anh


You need two things to precisely define the scroll position of a listView:

To get current position:

int firstVisiblePosition = listView.getFirstVisiblePosition(); 
int topEdge=listView.getChildAt(0).getTop(); //This gives how much the top view has been scrolled.

To set the position:

listView.setSelectionFromTop(firstVisiblePosition,0);
// Note the '-' sign...  
listView.scrollTo(0,-topEdge);
like image 1
Rahul Ogale Avatar answered Oct 13 '22 23:10

Rahul Ogale