android获取listview的滚动位置,填充不同的高度

时间:2012-09-27 14:51:09

标签: android listview android-listview

在android中,我如何获得listview的滚动位置?

我知道我可以使用以下代码检索统一填充列表视图的滚动位置:

int scrollY = -this.getChildAt(0).getTop() + this.getFirstVisiblePosition()* this.getChildAt(0).getHeight();

代码假设列表视图中的所有子项(项目)的高度相等(this.getChildAt(0).getHeight()

现在,如果我使用不同大小的项目填充我的列表视图,我如何获得正确的滚动位置?

我的listview看起来像这样: enter image description here

这就是我需要滚动位置的原因:

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;
}

我需要在listview的滚动之后绘制一个指示符

我会像

一样调用它
@Override
protected void onDraw(Canvas canvas) {
    canvas.save();
    canvas = drawIndicator(canvas);
    super.onDraw(canvas);
    canvas.restore();
}

3 个答案:

答案 0 :(得分:3)

假设您知道所有项目的大小:

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;

并使用适配器:

 private int getHightForViewType(int itemViewType) {

        int hightItem;
        switch (itemViewType) {
            case 0:
                hightItem = 100;
                break;

            default:
                hightItem = 60;
                break;
        }
        return hightItem;

    }

答案 1 :(得分:1)

或:

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;
}

这应该在:

中调用
public void onScroll(AbsHListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)

仅在从位置0滚动手动完成时才起作用,而不是以编程方式完成。

答案 2 :(得分:0)

我遇到了同样的问题,但我在每个项目中使用了带有随机长度文本的listView,因此我事先并不知道项目高度。 我的实施:

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];
}

我认为如果listView的任何元素发生了变化(添加/删除/更改高度),就会出现问题。滚动listView时也会计算高度,如果以编程方式滚动listView则会出现问题。 这非常令人难过,listView实现阻止了对Y位置的轻松访问:(

相关问题