Reputation: 8962
In android, how do i get the scroll position of the listview?
I know that I can retrieve the scroll position of a uniform populated listview with the following code:
int scrollY = -this.getChildAt(0).getTop() + this.getFirstVisiblePosition()* this.getChildAt(0).getHeight();
the code assumes all heights of children(item) in the listview to be equal(this.getChildAt(0).getHeight()
)
Now, if i populate my listview with not equally sized items, how do i get the proper scroll position?
My listview looks something like this:
This is why I need the scroll position:
private Canvas drawIndicator(Canvas canvas) {
int scrollY = getCurrentScrollPosition();
paint.setColor(Color.GRAY);
paint.setAlpha(100);
canvas.drawRect(getLeft(), indicatorPosition[0] - scrollY, getRight(), indicatorPosition[1]
- scrollY, paint);
//Log.d(VIEW_LOG_TAG, "drawIndicator:" + (indicatorPosition[1] -
//scrollY));
paint.setColor(Color.parseColor("#47B3EA"));
canvas.drawRect(getLeft(), indicatorPosition[1] - scrollY - (indicatorHeight / 2),
getRight(), indicatorPosition[1] - scrollY + indicatorHeight, paint);
return canvas;
}
i need to draw a indicator that follows the scroll of the listview
i would invoke it like
@Override
protected void onDraw(Canvas canvas) {
canvas.save();
canvas = drawIndicator(canvas);
super.onDraw(canvas);
canvas.restore();
}
Upvotes: 1
Views: 6105
Reputation: 3397
I faced with same problem, but I used listView with random lenght text inside each item hence I don't know item height in advance. My implementation:
private static int[] heights;
public static int getScrollY(ListView lv) {
if (heights == null || lv.getCount() != heights.length) {
heights = new int[lv.getCount()];
}
View c = lv.getChildAt(0);
if (c == null) {
return 0;
}
int firstVisiblePosition = lv.getFirstVisiblePosition();
if (firstVisiblePosition < lv.getCount() && heights[firstVisiblePosition + 1] == 0) {
heights[firstVisiblePosition + 1] += heights[firstVisiblePosition] + c.getHeight();
}
return -c.getTop() + heights[firstVisiblePosition];
}
I think there are problems if any element of listView changed (add/remove/change height). Also height computes when you scroll listView and there is problem if you scroll listView programmatically. This is very sad, that listView implementaion prevents easy access to scroll Y position :(
Upvotes: 0
Reputation: 7226
or:
private Dictionary<Integer, Integer> listViewItemHeights = new Hashtable<Integer, Integer>();
private int getScroll() {
View c = listView.getChildAt(0); //this is the first visible row
int scrollY = -c.getTop();
listViewItemHeights.put(listView.getFirstVisiblePosition(), c.getHeight());
for (int i = 0; i < listView.getFirstVisiblePosition(); ++i) {
if (listViewItemHeights.get(i) != null) // (this is a sanity check)
scrollY += listViewItemHeights.get(i); //add all heights of the views that are gone
}
return scrollY;
}
This should be invoked in:
public void onScroll(AbsHListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
will work only when scrolling from position 0 was done manually, not programatically.
Upvotes: 1
Reputation: 2555
Assuming that you know the size of All your items type:
int currentY = 0;
for (int i = 0; i < listView.getFirstVisiblePosition(); i++) {
int type = listView.getAdapter().getItemViewType(i);
currentY += getHightForViewType(type);
}
int scrollY = -listView.getChildAt(0).getTop() + currentY;
and using your adapter:
private int getHightForViewType(int itemViewType) {
int hightItem;
switch (itemViewType) {
case 0:
hightItem = 100;
break;
default:
hightItem = 60;
break;
}
return hightItem;
}
Upvotes: 3