如何刷新ListView,以便当页脚出现并重叠时,所选项目将完全可见?

时间:2013-02-19 16:21:18

标签: android

我有一个ListView,其中包含一些复选框和一个页脚,我必须在选中其中一个复选框时显示。

我想要实现的是,如果我点击一个与此页脚重叠的项目,ListView会自动滚动显示此项目。请注意,ListView已正确放置,可以进一步滚动。

我在onItemClicked函数中尝试了这个,到目前为止还没有工作:

if (mFooterView.getVisibility() != View.VISIBLE) {
    mFooterView.setVisibility(View.VISIBLE);

    mImagesListView.smoothScrollToPosition(position);
}

问题似乎是smoothScrollToPosition使用当前测量,该测量由mFooterView.setVisibility(View.VISIBLE)无效。然而,在下次重绘之前,新测量似乎不可用。

无论如何我能达到这个效果吗?非常感谢。

1 个答案:

答案 0 :(得分:0)

在检查ListView的源代码一段时间之后,我设法通过从ListView.onSizeChanged()获取灵感来解决这个问题。关键是在ListView实际调整大小后进行滚动。我们可以使用post函数来完成此操作。

这里是代码(注意它不会滚动,只是设置正确的位置,但你明白了):

public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {

    if (mFooterView.getVisibility() == View.GONE) {
        mFooterView.setVisibility(View.VISIBLE);

        // at this point, the listview's height hasn't changed yet
        int listOldHeight = parent.getHeight();

        if (mItemAutoVisibilityScroller == null) {
            mItemAutoVisibilityScroller = new ItemAutoVisibilityScroller();
        }

        // allow the list to resize
        mFooterView.post(mItemAutoVisibilityScroller.setup(listOldHeight, position, view.getTop(), view.getHeight()));
    } else {
        mFooterView.setVisibility(View.GONE);
    }
}

private class ItemAutoVisibilityScroller implements Runnable {
    private int mListOldHeight;
    private int mPosition;
    private int mItemTop;
    private int mItemHeight;

    public ItemAutoVisibilityScroller setup(int listOldHeight, int position, int itemTop, int itemHeight) {
        mListOldHeight = listOldHeight;
        mPosition = position;
        mItemTop = itemTop;
        mItemHeight = itemHeight;
        return this;
    }

    public void run() {
        final int textTop = mFooterView.getTop();

        // is the item cut by the footer?
        if (mItemTop + mItemHeight > textTop) {

            int newItemTop = mListOldHeight - mFooterView.getHeight() - mItemHeight;
            if (newItemTop < 0) {
                newItemTop = 0;
            }

            // move the item just above the footer
            mListView.setSelectionFromTop(mPosition, newItemTop);
        }
    }
}