从适配器内部处理多个getView调用的最佳方法

时间:2010-05-20 10:52:25

标签: android listview

我有ListView个自定义ArrayAdapter。此ListView中的每一行都有一个图标和一些文本。这些图标在后台下载,缓存,然后使用回调,在各自的ImageViews中替换。每次getView()运行时都会触发从缓存或下载中获取缩略图的逻辑。

现在,据罗曼盖伊说:

  

“绝对没有保证   getView()的顺序   叫了也没多少次。“

我已经看到过这种情况,因为一行大小为2的getView()被调用了六次!

如何更改代码以避免重复的缩略图获取请求并处理视图回收?

感谢。

7 个答案:

答案 0 :(得分:14)

确切地说,这可能发生在例如你有

的时候
android:layout_height="wrap_content"
ListView定义中

。将它改为fill_parent / match_parent会避免它。

答案 1 :(得分:8)

来自api。

public abstract View   getView  (int position, View  convertView, 
                                 ViewGroup  parent)

convertView - 如果可能,重用旧视图。注意:在使用之前,应检查此视图是否为非null且类型是否合适。如果无法转换此视图以显示正确的数据,则此方法可以创建新视图。

因此,如果已经为此特定索引调用了getView,那么convertView将是从第一次调用返回的View对象。

你可以做类似的事情。

if(!(convertView instanceof ImageView)){
   convertView = new ImageView();
   //get image from whereever
} else {} // ImageView already created

答案 2 :(得分:1)

我正在尝试同样的问题,我将listView的layout_height更改为match_parent解决了我的问题。

答案 3 :(得分:1)

我的理解是你需要在这里使用ViewHolder设计模式。只使用返回的convertView可以导致重用前一个视图(在这种情况下分配了一些其他图像)。

public class ImageAdapter extends ArrayAdapter<String> {

  // Image adapter code goes here.

  private ViewHolder {
    public ImageView imageView;
    public String url;
  }

  @Override
  public View getView(final int position, View convertView, ViewGroup parent) {
    View view = null;
    ViewHolder viewHolder;
    String url = getUrl(position);
    if (convertView == null) {
      // There was no view to recycle. Create a new view.
      view = inflator.inflate(R.layout.image_layout, parent, false);
      viewHolder = new ViewHolder();
      viewHolder.imageView = (ImageView) view.findViewById(R.id.image_view);
      viewHolder.url = url;
      view.setTag(viewHolder);
    } else {
      // We got a view that can be recycled.
        view = convertView;
        viewHolder = ((ViewHolder) view.getTag());
        if (viewHolder.url.equals(url)) {
          // Nothing to do, we have the view with the correct info already.
          return view;
        }
    }

    // Do work to set your imageView which can be accessed by viewHolder.imageView

    return view;
  }
}

答案 4 :(得分:0)

更好的方法是使用缩略图(位图)和文本创建对象。如果缩略图在对象中不可用,请阅读缩略图。

答案 5 :(得分:0)

在适配器中创建一个ImageView对象数组,并在检索它们时缓存它们(无论是从缓存还是Web)。例如,在getView中,在获取ImageView之前,检查它是否已经在您的本地数组中,如果是这样,使用它,如果不是fetch,一旦在本地ImageView数组中收到存储以供将来使用。

答案 6 :(得分:0)

我的Fragment.xml有一个ListView,这个ListView的布局设置是 android:layout_height =“wrap_content”,这个ListView稍后会绑定到SimpleCursorAdapter。然后我在ViewBinder中遇到同样的问题被调用3次。将layout_height =“wrap_content”更改为“95p”后问题得以解决。我确实认为“wrap_content”高度导致了这个问题。 尝试修改Fragment.xml,我想3次调用将不再存在。

相关问题