Android – 获取ListView项目高度?

当列表中没有实际项目时,有没有办法在代码中获取ListViewItem高度?

我的ListViewItem布局

 ...  

我试图使用Inflater来获取它:

 View convertView = LayoutInflater.from( this ) .inflate( R.layout.mail_list_row, null ); int itemHeight = convertView.getHeight(); 

但它返回0;

谢谢!

在android中,只有在渲染完成时才为视图指定宽度和高度。 因此,除非你的列表被删除,否则你将无法获得listItemHeight。 您的问题的解决方案可能是您设置列表项的最小高度,以便您至少使用某些内容而不是硬编码高度和宽度。

试试这个,它会对你有用。

 private static final int UNBOUNDED = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); // To calculate the total height of all items in ListView call with items = adapter.getCount() public static int getItemHeightofListView(ListView listView, int items) { ListAdapter adapter = listView.getAdapter(); int grossElementHeight = 0; for (int i = 0; i < items; i++) { View childView = adapter.getView(i, null, listView); childView.measure(UNBOUNDED, UNBOUNDED); grossElementHeight += childView.getMeasuredHeight(); } return grossElementHeight; } 

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; } 

正如上面的hariseldon78所指出的,这些解决方案都没有解决真正的问题,即在渲染之前确定列表项行的高度。 我有同样的问题,因为我想将一些图像缩放到我的ListView项目行的高度,并且不想将它们缩放到固定值。 如果主题导致我的行布局的其他部分的文本高度不同,我想要高度,以便在我的适配器的getView例程中,我可以相应地调整bmap的大小。 我正在努力解决getHeight和所有测量高度报告为零的问题,直到渲染行为止。 我后来看到高度正确的为时已晚。

我的解决方案是第一次通过getView创建一个onLayoutChangedListener(),并且只针对第0行。只要第一个位置(0)的getView完成执行,侦听器就会触发,那时“bottom”参数会告诉你行的高度。 我将其记录在自定义适配器类variables中,因此它可用作高度参数,而无需再次获取高度。

监听器将其自身注册为执行的一部分。 这为行1-N提供了适当的高度,但没有为行0提供适当的高度。 对于第零行,我做了一些非常讨厌的事情。 在设置另一个自定义适配器类variables来控制递归之后,我让我的侦听器为第0行调用了getView AGAIN。 第二次getView(0)运行它将不会设置监听器,并将find一个有效的高度参数来操作,一切都很好。

代码如下 – 没有必要告诉我这是多么的AWFUL – 如果android没有必要让它变得非常难以分辨我创建的视图有多大是当我完成基于渲染参数的填充视图时表面我不必做这个丑陋但它的确有效。 对不起,如果代码格式很糟糕……

 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; }