Android ListView正在回收仍在屏幕上的项目

时间:2011-04-20 21:46:48

标签: java android listview

我正在使用ListView,并将自定义对象扩展到getView方法。

我的问题在listview触发onItemClicked事件时开始,它会重新绘制项目。

这不是问题。出现实际问题是因为我正在回收getView给我的项目。

在我开始之前,这是我正在使用的代码。

public View getView(int position, com.abc.rxcard.Item itemAtPosition,
        View convertView, ViewGroup parent) {
    LinearLayout thisItem;
    //Get the current alert object

    //Inflate the view
    if(convertView==null)
    {
        thisItem = new LinearLayout(this);
        String inflater = Context.LAYOUT_INFLATER_SERVICE;
        LayoutInflater vi;
        vi = (LayoutInflater)this.getSystemService(inflater);
        vi.inflate(R.layout.offerrow, thisItem, true);
    }
    else
    {
        thisItem = (LinearLayout) convertView;
    }

    Log.d("thisItem","This Item is Index " + position + " " + thisItem.toString() + " " + Integer.toHexString(System.identityHashCode(thisItem)));


    //Get the text boxes from the listitem.xml file
    TextView caption =(TextView)thisItem.findViewById(R.id.caption);
    TextView subText =(TextView)thisItem.findViewById(R.id.subText);
    ImageView icon = (ImageView)thisItem.findViewById(R.id.offerIcon);

    //Assign the appropriate data from our alert object above
    caption.setText(itemAtPosition.text());
    subText.setText(itemAtPosition.subText());
    MyUtils.setImageFromURLInBackgroundThread(icon, itemAtPosition.icon());


    return thisItem;
}

当我点击这些项目时问题就出现了。 日志输出如下

04-20 14:36:28.402: DEBUG/thisItem(12495): This Item is Index 0 android.widget.LinearLayout@44db1c50 44db1c50
04-20 14:36:28.432: DEBUG/thisItem(12495): This Item is Index 1 android.widget.LinearLayout@44da9038 44da9038
04-20 14:36:28.442: DEBUG/thisItem(12495): This Item is Index 2 android.widget.LinearLayout@44d2ee48 44d2ee48
04-20 14:36:28.932: DEBUG/thisItem(12495): This Item is Index 0 android.widget.LinearLayout@44d2ee48 44d2ee48
04-20 14:36:28.952: DEBUG/thisItem(12495): This Item is Index 1 android.widget.LinearLayout@44da9038 44da9038
04-20 14:36:28.962: DEBUG/thisItem(12495): This Item is Index 2 android.widget.LinearLayout@44db1c50 44db1c50
04-20 14:36:29.622: DEBUG/thisItem(12495): This Item is Index 0 android.widget.LinearLayout@44db1c50 44db1c50
04-20 14:36:29.652: DEBUG/thisItem(12495): This Item is Index 1 android.widget.LinearLayout@44da9038 44da9038
04-20 14:36:29.662: DEBUG/thisItem(12495): This Item is Index 2 android.widget.LinearLayout@44d2ee48 44d2ee48

你可以看到索引0和2来回翻转项目。现在,如果项目实际上不在屏幕上,这将不是问题。但是当我点击项目时(因为图像是在后台线程中加载的)我在第1项和第3项上的图像每次点击都来回翻转。

这似乎是一种不良行为 我不确定世界上要做什么来解决这个问题。是否有一个设置或其他东西可以放在ListView上以阻止它这样做?

2 个答案:

答案 0 :(得分:3)

事实证明,回收商正在检查我的所有物品并将它们放入废料堆中,因为它会在这个运行周期中刷新它们。我遇到的问题是因为它以相反的顺序遍历项目,我应该理所当然地认为我需要擦除对象然后再次设置它的值。

我对此问题的解决方法是将我正在下载的图像缓存到指定位置的磁盘至少一分钟。当刷新发生时,它将尝试从缓存加载图像,而不是每次都下载它。并且只会在图像过期时下载。从而立即用所需的图像替换图像,而不是保留现有的废料图像。

我面临的问题已经解决,但事实仍然是他们回收屏幕上的项目....很难相信在项目上点击整个ListView将刷新,所有项目将被重新创造。但是当你把它浸入java中时,这就是cookie崩溃的方式......

答案 1 :(得分:0)

之前我遇到过同样的问题。

我认为问题出在您的背景图片线程下载器上。如果您非常快速地滚动列表视图,并且因为同一行视图被反复重复使用,可能会让所有这些图像尝试下载到相同的“图标”图像视图,并将图像设置为一个顶部另一个,它产生图像来回切换的效果。

我的解决方案是在调用图像下载程序之前在图标图像视图上设置带有唯一标识符的标记。比如说:

icon.setTag(imageUrl);

MyUtils.setImageFromURLInBackgroundThread(icon, itemAtPosition.icon(), imageUrl);

在你的setImageFromURLInBackgroundThread()方法中,当你在线程上完成下载图像时,检查图标视图以查看下载URL是否与imageUrl匹配,然后再设置为图标图像视图。例如:

if (icon.getTag() != null) {
    viewTagUrl = String.valueOf(icon.getTag());
}

if(imageUrl.equalsIgnoreCase(viewTagUrl)) {
    icon.setImageBitmap(bitmap);
}

另外,由于图像下载需要一段时间,我还会在运行线程下载图像之前清理图像视图并设置默认图像。

icon.setImageBitmap(null);
icon.setImageResource(defaultImage);
...
downloadThread.start();