当列表中没有实际项目时,有没有办法在代码中获取ListViewItem高度?
我的ListViewItem布局:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight">
...
</LinearLayout>
我试图使用Inflater来获取它:
View convertView = LayoutInflater.from( this )
.inflate( R.layout.mail_list_row, null );
int itemHeight = convertView.getHeight();
但它返回0;
谢谢!
答案 0 :(得分:11)
Dwivedi Ji
代码的优化版本,具有分隔符高度且没有不必要的参数:
private int calculateHeight(ListView list) {
int height = 0;
for (int i = 0; i < list.getCount(); i++) {
View childView = list.getAdapter().getView(i, null, list);
childView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
height+= childView.getMeasuredHeight();
}
//dividers height
height += list.getDividerHeight() * list.getCount();
return height;
}
答案 1 :(得分:4)
在android中,只有在渲染完成时才会为视图指定宽度和高度。所以,除非你的列表被删除,否则你将无法获得listItemHeight。您的问题的解决方案可能是您设置列表项的最小高度,以便您至少使用某些内容而不是硬编码高度和宽度。
答案 2 :(得分:2)
正如上面的hariseldon78所指出的,这些解决方案都没有解决真正的问题,即在渲染之前确定列表项行的高度。我有同样的问题,因为我想将一些图像缩放到我的ListView项目行的高度,并且不想将它们缩放到固定值。如果主题导致我的行布局的其他部分的文本高度不同,我想要高度,以便在我的适配器的getView例程中,我可以相应地调整bmap的大小。我正在努力解决getHeight和所有测量高度报告为零的问题,直到渲染行为止。我后来看到高度正确为时已晚。
我的解决方案是第一次通过getView创建一个onLayoutChangedListener(),仅用于第0行。一旦第一个位置(0)的getView完成执行,侦听器就会触发,并且那时“bottom”参数会告诉你行的高度。我将其记录在自定义适配器类变量中,因此它可用作高度参数,而无需再次获取高度。
侦听器将其自身注册为执行的一部分。这为行1-N提供了适当的高度,但没有为行0提供适当的高度。对于第零行,我做了一些非常讨厌的事情。在设置另一个自定义适配器类变量来控制递归之后,我让我的侦听器为第0行调用了getView AGAIN。第二次运行getView(0)时,它不会设置监听器,并且会找到一个有效的高度参数来运行,一切都很好。
代码如下 - 没有必要告诉我AWFUL是怎么回事 - 如果android没有必要让它变得非常难以分辨我创建的视图有多大,那就是当我完成基于渲染的视图填充时表面的parms我不必做这个丑陋但它的工作原理。对不起,如果代码格式很糟糕......
int mHeight = 0;
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
... usual boiler plate stuff
// JUST THE FIRST TIME
if (position == 0 && mHeight == 0) {
final View ref = convertView;
convertView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
public void onLayoutChange(View v, int left, int top, int right,
int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
ref.removeOnLayoutChangeListener(this);
mHeight = bottom;
firstTime = false;
// NOW LETS REGET THE FIRST VIEW WITH THE HEIGHT CORRECT
int visiblePosition = getListView().getFirstVisiblePosition();
View view = getListView().getChildAt(0 - visiblePosition);
getListAdapter().getView(0, view, getListView());
// RECURSION LOL
}
});
}
// Configure the view for this row
....
// HOW BIG IS THE VIEW?
// NOW IF NOT FIRSTTIME (MHEIGHT != 0)
if (mHeight != 0) {
// DO OUR IMAGE SETUP HERE CAUSE mHeight is RIGHT!
Log.d(TAG, "mHeight=" + mHeight);
}
return convertView;
}