首页 文章

listview回收奇怪的空白空间

提问于
浏览
2

我在这个问题上有一个类似的问题: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 回答

  • 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"即使有空的空间也不会改变 .

  • 1

    尝试在图片和文字视图上使用requestLayout . 它将帮助listview重新计算回收视图的高度 .

相关问题