我有一个包含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;
}
}
答案 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库来缓存图像并在
时清除它加载了许多图像以流动您的列表视图: