正如上面的 hariseldon78 指出的那样,这些解决方案都没有解决真正的问题,即在呈现之前确定列表项行的高度。我遇到了同样的问题,因为我想将一些图像缩放到我的 ListView 项目行的高度,并且不想将它们缩放到固定值。如果主题导致我的行布局的其他部分中的文本高度不同,我想要高度,以便在我的适配器的 getView 例程中我可以相应地调整 bmap 的大小。我一直在努力解决 getHeight 和所有测量高度报告为零的问题,直到该行被渲染。对我来说,后来看到正确的高度为时已晚。
我的解决方案是第一次通过 getView 创建一个 onLayoutChangedListener() 并且仅针对第 0 行。一旦第一个位置 (0) 的 getView 完成执行,侦听器就会触发,届时“bottom”参数会告诉你行的高度。我将此记录在自定义适配器类变量中,因此它可以作为高度参数使用,而无需再次获取高度。
侦听器在其执行过程中注销自己。这为第 1-N 行提供了适当的高度,但不为第 0 行提供了适当的高度。对于第零行,我做了一些非常讨厌的事情。在设置另一个自定义适配器类变量来控制递归之后,我让我的侦听器再次为第 0 行调用 getView。第二次 getView(0) 运行它不会设置监听器,并且会找到一个有效的高度参数来操作,一切都很好。
代码如下 - 无需告诉我这是多么糟糕 - 如果 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;
}