listview回收奇怪的空白空间

时间:2012-06-18 21:28:15

标签: android listview listadapter recycle

我遇到与此问题相似的问题:ListView and rows recycling problem

以上解决了。但同样的解决方案对我不起作用。

我有一个由textview组成的列表视图。每个文本视图可以包含可变数量的图像。我正在使用html.imagegetter获取图像,我在列表适配器的getview方法中使用了回收。

如果textview中有一个或多个图像,则其高度可以适合其内容。当此文本视图被回收并且新内容未填充之前定义的高度时,将显示空白空间。

问题是我无法恢复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" />

问题: listview回收机制无法根据新内容计算已用视图的新高度。 没有回收,就太慢了。

2 个答案:

答案 0 :(得分:2)

所以,基本上你的问题在于回收视图。当您的视图从XML中膨胀时,他们会查看图像并确定其高度。这样可以正常工作,因为inflater可以导致高度为“wrap_content”,即高度最高的子组件 - 这是动态的。

然而,当你的getview回收旧视图时(由于某种原因)它不会更新行的高度,也不是你(你之前从未必须这样做,因为inflater会自动从“wrap_content”处理它) )。从您描述的内容中可以看出,您只是获得了一行,无论先前设置的视图高度如何(此前一个值由inflater自动设置)。

您的两个解决方案是:

  1. 不回收视图 - 每次只需要新建一个新视频。您将看到性能命中,这可能仅在具有约50个元素或更多元素的列表中才会被注意到。如果它是一个小列表,这可能是最简单的(代码方式)选项,尽管它仍然会运行稍慢。
  2. 继续回收视图 - 如果你选择这个,你必须设置行的高度(或文本视图,无论是什么决定它)你自己基于图像高度。这是可行的,但需要更多的工作。我建议
  3. 秘密选项3 - 规范化图像高度 - 如果您 a。)喜欢继续回收视图,但 b。) don'我想编写代码来手动设置行高和 c。)调整图像大小不会杀死你的应用程序,你可以使用setMaxHeight(int)方法来确保你的所有图像都是相同的高度(或使用类似this的方法将图像大小调整为预定大小)
  4. 注意:我非常肯定(几乎可以肯定),通常,如果将height设置为“wrap_content”,它将换行到新的内容大小(因为它通常在内容时更新大小已更新)。我不知道为什么这不会发生在你身上 - 可能是因为“wrap_content”中的某些内容将其大小设置为具体值而因此没有调整大小,所以“wrap_content”即使在那里也没有改变是空的空间。

答案 1 :(得分:1)

尝试在图片和文字视图上使用requestLayout。这将有助于listview重新计算回收视图的高度。