listview回收奇怪的空白空间 [英] listview recycling strange empty space

查看:104
本文介绍了listview回收奇怪的空白空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我与此问题中的问题类似: ListView和行回收问题

I have a similar problem to the one in this question: ListView and rows recycling problem

以上已解决.但相同的解决方案对我不起作用.

Above is solved. but same solution does not work for me.

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

I have a listview consisting of textviews. Each textview can contain variable number of images. I am getting images with html.imagegetter and I am using recycling in getview method of list adapter.

如果文本视图中有一个或多个图像,它将具有一定的高度以适合其内容.当此textview被回收并且新内容未达到之前定义的高度时,将出现空白区域.

If there is one or more images in a textview, it will have a height to be able to fit its content. When this textview is recycled and new content does not fill the height defined before, then empty space will appear.

问题是我无法恢复getview中的textview高度,因为我不知道下一个列表项的高度.

The problem is that I can't restore the textview height in getview because I dont know what height the next list item will have.

这是我的观点:

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回收机制无法根据其新内容来计算二手视图的新高度. 如果没有回收,那就太慢了.

THE PROBLEM: The listview recycling mechanism can't calculate the new height for used views according to its new contents. Without recycling, it is too slow.

推荐答案

因此,实质上,您的问题是回收视图.当您的视图因XML而膨胀时,它们将查看图像并确定高度.这很好用,因为充气机可以使高度为"wrap_content",而无论子组件的最高身高是多少-这都是动态的.

So, essentially your problem is with recycling the views. When your views get inflated from XML they look at the images and decide how tall to be. This works fine because the inflater can cause the height to be "wrap_content" aka however tall the tallest child component is - this is dynamic.

但是,当您的getview回收旧视图时,它(出于某种原因)并没有更新行的高度,您也不是(因为充气机会自动通过"wrap_content"自动处理它,所以您以前从未这样做) ).从您描述的内容看来,您只是得到了一行,而无论该视图的高度是先前设置的(此先前的值都是由充气机自动设置的).

However, when your getview recycles the old views it (for some reason) isn't updating the height of the rows, and neither are you (which you never had to do before because the inflater handles it automatically from "wrap_content"). It would appear from what you described that you just get a row with whatever the height of the view happened to be set at previously (this previous value was set by the inflater automatically).

您的两个解决方案是:

  1. 请勿回收视图-每次都需要添加一个新视图.您会看到性能下降的情况可能只有在包含约50个或更多元素的列表中才可以注意到.如果列表很小,这可能是最简单的(按代码显示)选项,尽管它的运行速度仍会稍慢一些.
  2. 继续回收视图-如果选择此视图,则必须基于图像高度.这是可行的,但将需要更多的工作.我建议
  3. 秘密选项3-标准化图像高度-如果您愿意 a.)希望继续回收视图,但 b.)则不要不想编写代码来手动设置行高并 c.).调整图像的大小不会杀死您的应用程序,您可以使用setMaxHeight(int)方法来确保所有图像都是相同的高度(或使用之类的方法将图像调整为预定大小)
  1. Don't recycle the views - just inflate a new one every time. You will see a performance hit which will probably only be noticeable at lists with ~50 elements or more. If it is a small list this may be the easiest (code-wise) option, although there it will still operate slightly slower.
  2. Keep recycling the views - if you pick this you will have to set the height of the row (or text view, whatever is determining it) yourself based on the image heights. This is doable but will require more work. I'd suggest
  3. secret option 3 - normalize the image heights - If you would a.) like to continue recycling views but b.) don't want to write the code to set the row heights manually and c.) resizing the images wouldn't kill your app, you could use the setMaxHeight(int) method to make sure all of your images are the same height (or use a method like this to resize the images to a predetermined size)

注意:我很确定(几乎可以肯定),通常,如果将height设置为"wrap_content",它将自动换成新的内容大小(因为通常在内容出现时会更新大小)已更新).我无法说出为什么这种情况对您不发生-可能是因为"wrap_content"中的某些内容的大小设置为具体值,因此无法调整大小,因此即使存在,"wrap_content"也不会改变是空的空间.

Note: I am pretty sure (almost certain) that, normally, if height is set to "wrap_content" it would wrap to the new content size (since it normally updates the size when the content is updated). I couldn't say why this is not happening for you - it may be that something inside the "wrap_content" has its size set to a concrete value and thus isn't resizing, so the "wrap_content" isn't changing even though there is empty space.

这篇关于listview回收奇怪的空白空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆