通过检查ViewHolder是否使用相同的模型对象来优化ListAdapter

时间:2012-06-21 14:09:40

标签: android android-listview

我想知道检查ViewHolder是否使用相同的模型对象是一个很好的优化。这适用于填充View返回的getView()费用昂贵的情况。

这假设视图内容不会改变 - 我认为这是常见的情况。

例如,标准模式是:

public View getView(int position, View convertView, ViewGroup parent) {
            Model model = models.get(position);
    if (convertView != null) {
                    // View was recycled. Get the holder.
        viewHolder = (ViewHolder) convertView.getTag();
    } else {
                    // Inflate a new layout and create a holder
        convertView = inflater.inflate(R.layout.item_layout, null);
        viewHolder = new ViewHolder();
        viewHolder.name = (TextView) convertView.findViewById(R.id.name);
        viewHolder.img = (ImageView) convertView
                .findViewById(R.id.img);
        convertView.setTag(viewHolder);
    }

    // Fill in the content
    Bitmap imgBitmap = loadBitmapFor(model.getName());

    if (imgBitmap != null) {
        viewHolder.img.setVisibility(View.VISIBLE);
        viewHolder.img.setScaleType(ImageView.ScaleType.FIT_XY);
        viewHolder.img.setImageBitmap(imgBitmap);
            }

    viewHolder.name.setText(model.getName());

    return convertView;
}

static class ViewHolder {
    TextView name;
    ImageView img;
}

我们通过检查ListView是否在同一位置查看同一个对象来优化:

public View getView(int position, View convertView, ViewGroup parent) {
            Model model = models.get(position);

            boolean recycled;
    if (convertView != null) {
                    // View was recycled. Get the holder.
        viewHolder = (ViewHolder) convertView.getTag();
                    recycled = true;
    } else {
                    // Inflate a new layout and create a holder
        convertView = inflater.inflate(R.layout.item_layout, null);
        viewHolder = new ViewHolder();
                    viewHolder.model = model;
        viewHolder.name = (TextView) convertView.findViewById(R.id.name);
        viewHolder.img = (ImageView) convertView
                .findViewById(R.id.img);
        convertView.setTag(viewHolder);
                    recycled = false;
    }

            // Skip the expensive content loading if we can
            if (recycled && (model == viewHolder.model) && (position == viewHolder.position)) {
                return convertView;
            }

    // Fill in the content
    Bitmap imgBitmap = loadBitmapFor(model.getName());

    if (imgBitmap != null) {
        viewHolder.img.setVisibility(View.VISIBLE);
        viewHolder.img.setScaleType(ImageView.ScaleType.FIT_XY);
        viewHolder.img.setImageBitmap(imgBitmap);
            }

    viewHolder.name.setText(model.getName());

    return convertView;
}

static class ViewHolder {
            int position; // for double checking_
            Model model;
    TextView name;
    ImageView img;                
}

1 个答案:

答案 0 :(得分:1)

由于视图回收工作主要是这样的:http://android.amberfog.com/wp-content/uploads/2010/02/listview_recycler.jpg

再循环视图的新位置和先前位置不太可能相同。

您应该专注于缓存 Bitmap。根据需要生成Bitmap,然后将它们放在缓存中。您可以使用LruCache(兼容性库中提供),如下所示:http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html