0

我希望能够采用 aListView并将特定行滚动到该Listview's边界的顶部,即使该行接近末尾并且通常无法在普通 android 中滚动那么高ListView(类似于 twitter当您深入了解特定推文并且该推文始终可以滚动到顶部时,即使它下面没有任何内容也可以使用。)

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

4

2 回答 2

2

看起来你是 listview 的setSelectionFromTop方法。

mListView.setSelectionFromTop(listItemIndex, 0);
于 2013-04-28T19:55:45.593 回答
-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,因此我们不会得到负高度)。这最终会在底部创建一个视图,该视图会根据其他项目的高度随意扩展,因此特定行始终可以滚动到列表顶部,无论它在列表中的哪个位置。

于 2013-06-13T03:52:02.987 回答