我在这个问题上有一个类似的问题:ListView and rows recycling problem
以上解决了 . 但同样的解决方案对我不起作用 .
我有一个由textviews组成的列表视图 . 每个文本视图可以包含可变数量的图像 . 我用html.imagegetter获取图像,我在列表适配器的getview方法中使用回收 .
如果文本视图中有一个或多个图像,则其高度可以适合其内容 . 当此文本视图被回收并且新内容未填充之前定义的高度时,将显示空白空间 .
问题是我无法恢复getview中的textview高度,因为我不知道下一个列表项的高度 .
这是我的getview:
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
View rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = context.getLayoutInflater();
rowView = inflater.inflate(resource, parent, false);
holder = new ViewHolder();
holder.imgAvatar = (ImageView) rowView.findViewById(R.id.imgAvatar);
holder.textDetails = (TextView) rowView.findViewById(R.id.textDetails);
holder.textPostTime = (TextView) rowView.findViewById(R.id.textPostTime);
holder.textPost = (TextView) rowView.findViewById(R.id.textPost);
rowView.setTag(holder);
} else {
holder = (ViewHolder) rowView.getTag();
}
holder.textDetails.setText(details.toString());
holder.textPostTime.setText(x.postTime);
holder.textPost.setText(Html.fromHtml(x.postBody, new URLImageGetter(holder.textPost, context), null, context));
return rowView;
}
这是行布局:
<TextView
android:ellipsize="none"
android:autoLink="web"
android:textColor="#000000"
android:id="@+id/textPost"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
THE PROBLEM: listview回收机制无法根据新内容计算已用视图的新高度 . 没有回收,它太慢了 .
2 回答
所以,基本上你的问题是回收视图 . 当您的视图从XML中膨胀时,他们会查看图像并确定其高度 . 这样可以正常工作,因为inflater可以导致高度为“wrap_content”,即高度最高的子组件 - 这是动态的 .
但是,当你的getview回收旧视图时(由于某种原因)它不会更新行的高度,你也不会(因为inflater会自动从“wrap_content”处理它)而你之前不必这样做 . 从您描述的内容中可以看出,您只是获得了一行,无论先前设置的视图高度如何(此前一个值由inflater自动设置) .
你的两个解决方案是:
Don't recycle the views - 每次只需要换一个新的 . 您将看到性能命中,这可能仅在具有约50个元素或更多元素的列表中才会被注意到 . 如果它是一个小列表,这可能是最简单的(代码方式)选项,尽管它仍然会运行稍慢 .
Keep recycling the views - 如果你选择这个,你必须根据图像高度自己设置行的高度(或文本视图,无论是什么决定它) . 这是可行的,但需要更多的工作 . 我建议
secret option 3 - normalize the image heights - 如果你想 a.) 喜欢继续回收视图但是 b.) 不想编写代码来手动设置行高,并且 c.) 调整图像大小不会杀死你的应用程序,你可以使用setMaxHeight(int)方法来确保所有图像的高度相同(或使用像this这样的方法将图像调整为预定大小)
注意:我很确定(几乎可以肯定)通常,如果将高度设置为"wrap_content",它将换行到新的内容大小(因为它通常在更新内容时更新大小) . 我无法调整大小,所以"wrap_content"即使有空的空间也不会改变 .
尝试在图片和文字视图上使用requestLayout . 它将帮助listview重新计算回收视图的高度 .