ListView getFirstVisiblePosition getFirstVisiblePosition getCount值

时间:2011-12-24 19:32:45

标签: android android-layout

我有一个自定义的ListView类(从ListView子类化),我需要它在最终视图元素的底部添加一个小填充,这样它就不会被我在屏幕底部的小条重叠。我只想在子视图越过列表视图的可见区域时执行此操作。我正在尝试使用此代码来实现此目的:

@Override
protected void onLayout (boolean changed, int left, int top, int right, int bottom) {
     super.onLayout(changed, left, top, right, bottom);

     // If there are hidden listview items we need to add a small padding to the last one so that it
     // partially hidden by the bottom sliding drawer handle
     if (this.getLastVisiblePosition() - this.getFirstVisiblePosition() + 1 > this.getCount()) {
         LinearLayout v2 = (LinearLayout) this.getChildAt(this.getCount() - 1);
         v2.setPadding(v2.getPaddingLeft(), v2.getPaddingTop(), v2.getPaddingRight(), 
                 v2.getPaddingBottom() + 5);
     }
 }

但是,getLastVisiblePostion(),getFirstVisiblePostion()和getCount()返回的值不会反映适配器的持有量。我假设这是因为适配器尚未通知ListView数据,但我无法弄清楚ListView实际知道数据的位置,因此具有正确的值。正在加载Activity时正在运行此代码。

在渲染过程的哪个阶段,我可以访问这些数据吗?我还应该说我使用AsyncTask从数据库加载数据,然后在那里创建适配器并将其添加到列表视图中。是否有一个事件我可以在ListView中使用,当适配器添加数据时会触发/导致listview呈现新项目?

2 个答案:

答案 0 :(得分:0)

我不确定它是否是最佳解决方案,但我知道在Android的pull-to-refresh实现的一个分支中,列表的高度与所有列表项的总高度进行比较。根据您所说的,听起来就像您正在寻找的信息相同,以确定是否应用额外的填充。

实施的相关部分有以下三种方法:

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if (mHeight == -1) {  // do it only once
        mHeight = getHeight(); // getHeight only returns useful data after first onDraw()
        adaptFooterHeight();
    }
}

/**
 * Adapts the height of the footer view.
 */
private void adaptFooterHeight() {
    int itemHeight = getTotalItemHeight();
    int footerAndHeaderSize = mFooterView.getHeight()
        + (mRefreshViewHeight - mRefreshOriginalTopPadding);
    int actualItemsSize = itemHeight - footerAndHeaderSize;
    if (mHeight < actualItemsSize) {
        mFooterView.setHeight(0);
    } else {
        int h = mHeight - actualItemsSize;
        mFooterView.setHeight(h);
        setSelection(1);
    }
}

/**
 * Calculates the combined height of all items in the adapter.
 * 
 * Modified from http://iserveandroid.blogspot.com/2011/06/how-to-calculate-lsitviews-total.html
 * 
 * @return 
 */
private int getTotalItemHeight() {
    ListAdapter adapter = getAdapter();
    int listviewElementsheight = 0;
    for(int i =0; i < adapter.getCount(); i++) {
        View mView  = adapter.getView(i, null, this);
        mView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
                MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
        listviewElementsheight+= mView.getMeasuredHeight();
    }
    return listviewElementsheight;
}

可以在GitHub上找到完整的源代码here

答案 1 :(得分:0)

getFirstVisiblePosition()返回的数字大于getCount()时,我遇到了类似的问题 通过调用listView.setAdapter(listView.getAdapter())修正了它。