2011-12-24 52 views
0

我有一个自定义的ListView类(从ListView中分类),我需要它添加一个小填充到最终视图元素的底部,这样它就不会与我所跨过的小酒吧重叠屏幕的底部。我只想在子视图越过listview的可见区域时执行此操作。我想利用这个代码来实现这一目标:ListView getFirstVisiblePosition getFirstVisiblePosition getCount values

@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实际知道数据的位置,因此具有正确的值。该代码正在加载活动时运行。

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

回答

0

我不知道这是否是最好的解决办法,但我知道,在上拉来刷新执行针对Android的分支之一,该列表的高度对所有列表的总高度相比,项目。从你所说的话来看,这听起来就是你想要确定是否应用额外填充的信息。

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

@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

+0

感谢您的回复,但仍然有同样的问题。我认为问题在于,当onLayout被调用时,适配器尚未告知有关项目的视图。当添加这些数据时,是否有某种类型的数据可以插入? – 2011-12-25 05:49:51

+0

当您在ListView上设置适配器时,您是否尝试将'mHeight'设置回'-1'?从它听起来,你第一次绘制完成后填充列表的方式,这意味着计算出的高度可能是'0',并且在您实际设置数据时不准确。因此你需要更新它。据我所知,没有特定的事件可以使用。如果是这样,上述代码中的解决方法将不是必需的。 – 2011-12-25 06:09:40

0

我也有类似的问题,当getFirstVisiblePosition()返回的数字比getCount()更大。
通过调用listView.setAdapter(listView.getAdapter())来修复它。