将ListView图像存储在缓存

时间:2016-05-30 17:55:49

标签: java android caching

我有一个包含100多个项目的ListView,每个项目都有不同的图像。图像已经在drawable文件夹中,因此我没有请求任何服务器。

当我滚动ListView时,由于手机必须再次渲染每个图像,有时它会变慢,看起来像低fps。出于测试目的,我对所有项目使用相同的图像,并且滚动更好,所以我认为问题确实是渲染所需的不同图像。

我的问题是:我可以将这些图像存储在缓存或其他内容上以使此滚动更加sm?这是我的ListView适配器代码:

public class AdapterItens extends BaseAdapter implements ListAdapter {

    private final JSONArray jsonArray;

    static class ViewHolder {
        ImageView itemAvatar;
        TextView itemName;
        TextView itemId;
    }

    public AdapterItens(JSONArray jsonArray) {
        this.jsonArray = jsonArray;
    }

    @Override
    public int getCount() {
        return jsonArray.length();
    }

    @Override
    public JSONObject getItem(int position) {
        return jsonArray.optJSONObject(position);
    }

    @Override
    public long getItemId(int position) {
        JSONObject jsonObject = getItem(position);
        return jsonObject.optLong("id");
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final ViewHolder viewHolder;

        if (convertView == null) {
             final LayoutInflater inflater = LayoutInflater.from(Controller.getContext());
             convertView = inflater.inflate(R.layout.item_layout, parent, false);

             viewHolder = new ViewHolder();
             viewHolder.itemAvatar = (ImageView) convertView.findViewById(R.id.avatar_item);
             viewHolder.itemName = (TextView) convertView.findViewById(R.id.name_item);
             viewHolder.itemId = (TextView) convertView.findViewById(R.id.id_item);

             convertView.setTag(viewHolder);
        } else {
             viewHolder = (ViewHolder) convertView.getTag();
        }

        final JSONObject jsonData = getItem(position);
        viewHolder.itemAvatar.setImageResource(Controller.getContext().getResources().getIdentifier(jsonData.getString("itemAvatar"), "drawable", Controller.getContext().getPackageName()));
        viewHolder.itemName.setText(jsonData.getString("itemName"));
        viewHolder.itemId.setText(jsonData.getString("itemId"));

        return convertView;
    }
}

2 个答案:

答案 0 :(得分:1)

我认为问题在于你“在飞行中”解析JSON。 首先使用AsyncTask中的对象将JSON解析为列表,每个对象将包含id,name和bitmap。

例如:

class YourObjectName {
    long id;
    String name;
    Bitmap bitmap;
}

您的代码如下所示:

static class ViewHolder {
    ImageView itemAvatar;
    TextView itemName;
    TextView itemId;
}

public ItemsAdapter (List<YourObjectName> yourObjectsList) {
    this.yourObjectsList = yourObjectsList;
}

@Override
public int getCount() {
    return yourObjectsList.size();
}

@Override
public YourObjectName getItem(int position) {
    return yourObjectsList.get(position);
}

@Override
public long getItemId(int position) {
    return yourObjectsList.get(position).id;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    final ViewHolder viewHolder;
    if (convertView == null) {
        final LayoutInflater inflater = LayoutInflater.from(Controller.getContext());
        convertView = inflater.inflate(R.layout.item_layout, parent, false);

        viewHolder = new ViewHolder();
        viewHolder.itemAvatar = (ImageView) convertView.findViewById(R.id.avatar_item);
        viewHolder.itemName = (TextView) convertView.findViewById(R.id.name_item);
        viewHolder.itemId = (TextView) convertView.findViewById(R.id.id_item);

        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }

    YourObjectName itemAtPosition = yourObjectsList.get(position);
    viewHolder.itemAvatar.setImageBitmap(itemAtPosition.bitmap);
    viewHolder.itemName.setText(itemAtPosition.name);
    viewHolder.itemId.setText(itemAtPosition.id);

    return convertView;
}

最后,您可以使用Glide或Picasso等图书馆在后台加载图片。

只需将此行替换为此库中的一个,而是将位图保存为drawable_id。

viewHolder.itemAvatar.setImageBitmap(itemAtPosition.bitmap);

滑翔: https://github.com/bumptech/glide

Glide.with(context)
      .load(itemAtPosition.drawable_id)
      .resize(width, height)
      .centerCrop()
      .into(viewHolder.itemAvatar);

毕加索: http://square.github.io/picasso/

Picasso.with(context)
       .load(itemAtPosition.drawable_id)
       .override(width, height)
       .centerCrop()
       .into(viewHolder.itemAvatar);

同时强烈建议使用recyclerview而不是listview,看一下接受的答案。 Android Recyclerview vs ListView with Viewholder

答案 1 :(得分:0)

您可以使用Universal Image Loader库来缓存图像并在

时清除它

加载了许多图像以流动您的列表视图:

https://github.com/nostra13/Android-Universal-Image-Loader