Android在ListView中获得精确的滚动位置

saa*_*az1 38 android android-listview

我想获得ListView滚动的精确像素位置.不,我不是指第一个可见的位置.

有没有办法实现这个目标?

saa*_*az1 79

好的,我找到了一个解决方法,使用以下代码:

View c = listview.getChildAt(0);
int scrolly = -c.getTop() + listview.getFirstVisiblePosition() * c.getHeight();
Run Code Online (Sandbox Code Playgroud)

它的工作方式是它获取第一个可见列表项的实际偏移量,并计算它与视图顶部的距离,以确定我们"滚动到"视图中的多少,所以现在我们知道我们可以计算其余的使用常规的getFirstVisiblePosition方法.

  • 只有当您的所有列表项都具有相同的高度时,这才是准确的. (93认同)
  • 如果ListView有标题怎么办? (6认同)

Mar*_*ria 29

只有当listview中的所有行都具有相同的高度并且没有标题(或者它与行的高度相同)时,Saarraz1的答案才有效.

请注意,一旦行消失在屏幕顶部,您就无法访问它们,因为您将无法跟踪它们的高度.这就是为什么你需要保存这些高度(或所有的累积高度).我的解决方案需要保持每个索引的高度字典(假设当列表第一次滚动到顶部时显示该列表).

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 当然,这仅在用户手动滚动所有列表项时才有效。如果您以编程方式设置列表位置,这将不起作用。 (2认同)

jar*_*ker 20

我想出的最简单的想法是扩展ListView并公开默认受保护的"computeVerticalScrollOffset",然后在xml布局中使用"com.your.package.CustomListView".

public class CustomListView extends ListView {

    public CustomListView(Context context) {
        super(context);
    }

    public CustomListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public int computeVerticalScrollOffset() {
        return super.computeVerticalScrollOffset();
    }
}
Run Code Online (Sandbox Code Playgroud)


cnn*_*nnr 9

如果有其他人在Google中找到这种方法来寻找一种方法来跟踪OnScrollListener中的相对滚动偏移 - 也就是说,自上次调用侦听器以来改变了Y - 这里是一个显示如何计算它的Gist.


Cra*_*ind 6

首先声明你的int变量以保持位置.

int position = 0;
Run Code Online (Sandbox Code Playgroud)

然后将scrollListener添加到ListView,

listView.setOnScrollListener(new OnScrollListener() {

        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            // TODO Auto-generated method stub

        }

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

        }
    });
Run Code Online (Sandbox Code Playgroud)

然后,在获取新数据或数据中的任何更改后,您需要设置listview当前位置

listView.setSelection(position);
Run Code Online (Sandbox Code Playgroud)

我在安装后使用我的适配器,对我来说工作正常..