ListView,特定行总是可以滚动到顶部?

时间:2013-04-28 19:41:22

标签: android listview android-listview

我希望能够获取ListView并将特定行可滚动到Listview's边界的顶部,即使该行接近结尾并且通常也不能在普通的android ListView中滚动那个高点(类似于当你钻进一个特定的推文时推特的工作方式,即使下面没有任何内容,推文仍然可以滚动到顶部。)

有什么方法可以轻松完成这项任务吗?我已经尝试测量我想要滚动到顶部的行并应用底部填充以考虑它需要的额外空间,但这会产生奇怪的结果(我认为因为在视图的测量通过期间更改填充等等决定)。在测量通过之前这样做是行不通的,因为测量的单元格高度(以及之后的任何单元格)尚未发生。

2 个答案:

答案 0 :(得分:2)

看起来像listview的setSelectionFromTop方法。

mListView.setSelectionFromTop(listItemIndex, 0);

答案 1 :(得分:-2)

我明白了;它有点复杂但似乎主要起作用:

public int usedHeightForAndAfterDesiredRow() {
    int totalHeight = 0;
    for (int index = 0; index < rowHeights.size(); index++) {
        int height = rowHeights.get(rowHeights.keyAt(index));
        totalHeight += height;
    }
    return totalHeight;
}

@Override
public View getView(int position, View convertView, final ViewGroup parent) {
    View view = super.getView(position, convertView, parent);

    if (measuringLayout.getLayoutParams() == null) {
        measuringLayout.setLayoutParams(new AbsListView.LayoutParams(parent.getWidth(), parent.getHeight()));
    }

    // measure the row ahead of time so that we know how much space will need to be added at the end
    if (position >= mainRowPosition && position < getCount()-1 && rowHeights.indexOfKey(position) < 0) {
        measuringLayout.addView(view, new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
        measuringLayout.measure(MeasureSpec.makeMeasureSpec(parent.getWidth(), MeasureSpec.EXACTLY), MeasureSpec.UNSPECIFIED);

        rowHeights.put(position, view.getMeasuredHeight());
        measuringLayout.removeAllViews();

        view.setLayoutParams(new AbsListView.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
    }

    if (position == getCount()-1 && view.getLayoutParams().height == 0) {
        // we know how much height the prior rows take, so calculate the last row with that.
        int height = usedHeightForAndAfterDesiredRow();
        height = Math.max(0, parent.getHeight() - height);
        view.getLayoutParams().height = height;
    }
    return view;
}

这是在我的适配器中。它是合并适配器的子类,但您可以将它放在代码中,并用生成行来替换超级调用。

getView()中的第一个if语句设置了一个仅用于测量的框架布局成员var的布局参数,它没有父视图。

第二个if语句计算行的所有行高,包括在我关心滚动到顶部的行的位置之后。 rowHeights是一个SparseIntArray。

最后一个if语句假设有一个额外的视图,其中布局参数已经设置在视图列表的底部,其唯一目的是透明并随意扩展。 usedHeightForAndAfterDesiredRow调用将从父视图的高度中减去所有预先计算的高度(最小值为0,因此我们不会得到负高度)。这最终会在底部创建一个基于其他项目高度随意扩展的视图,因此特定行始终可以滚动到列表顶部,无论它在列表中的位置如何。