在自定义的 SimpleAdapter 中通过 id 调用视图?

Calling view by id in customized SimpleAdapter?

我想在 SimpleAdapter 用于 ListView 时添加一些自定义操作。所以我写了一个MySimpleAdapter来扩展SimpleAdapter。如果图像 url 为空,我需要隐藏 ImageView。但是,当视图回收工作时,那些可见的视图 ImageView 在上下滚动时也会被隐藏。

代码如下:

public class MySimpleAdapter extends SimpleAdapter {
  ...
  public View getView(int position, View convertView, ViewGroup parent) {
    View vi = convertView;        
    vi=super.getView(position, convertView, parent);//other parts rather than the ImageView will behave normally

    @SuppressWarnings("unchecked")
    HashMap<String, Object> data = (HashMap<String, Object>) getItem(position);

    //below is the problematic part
    if(data.get("url")!=null){
        setImageWithUrl(data.get("url").toString(), (ImageView) vi.findViewById(R.id.my_image));//setImageWithUrl is a function containing my extra operations
    }else{
        ((ImageView) vi.findViewById(R.id.my_image)).setVisibility(View.GONE);//hide the image as it has a border but no content
    }

    //in contrast, setting image drawable is always right
    if(data.get("url2")!=null){
        setImageWithUrl(data.get("url2").toString(), (ImageView) vi.findViewById(R.id.my_image_2));
    }else{
      ((ImageView)vi.findViewById(R.id.my_image_2)).setImageDrawable(mContext.getResources().getDrawable(R.drawable.default_image));
    }
  }
}

问题就像(假设屏幕显示 3ListView:

[1=====] <a row with visible image
[2=====] <a row with visible image
[3=====] <a row with visible image
--------- below is out of screen
[4=====] <a row with hidden image

向下滚动到第 4th 行,这样 1th 就在屏幕之外了。然后滚动回 1th 并且 4th 超出屏幕。然后 1th 是隐藏图像 @id/my_image 的行。我认为这是由于“findViewById”。但是为什么用drawable资源设置图片总是对的(for @id/my_image_2)?

我不太熟悉充气机和回收机制的细节。我怎样才能在这段代码中避免这种情况?或者我需要使用其他适配器吗?

PS,

行xml结构简单,类似:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <TextView
        android:id="@+id/title_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <ImageView
        android:id="@+id/my_image"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@layout/border_style" />
    <ImageView
        android:id="@+id/my_image_2"
        android:layout_width="100dp"
        android:layout_height="100dp" />
    ...
</LinearLayout>

ListView 重用视图,因此您需要实现 hide/restore 逻辑。在代码中添加 set visibility 到 visible。

 //below is the problematic part
    if(data.get("url")!=null){
  ((ImageView) vi.findViewById(R.id.my_image)).setVisibility(View.VISIBLE);
        setImageWithUrl(data.get("url").toString(), (ImageView) vi.findViewById(R.id.my_image));//setImageWithUrl is a function containing my extra operations
    }else{
        ((ImageView) vi.findViewById(R.id.my_image)).setVisibility(View.GONE);//hide the image as it has a border but no content
    }