2016-05-30 4 views
0

У меня есть ListView с более чем 100 элементами, и каждый элемент имеет другое изображение. Изображения уже находятся в папке с возможностью рисования, поэтому я не запрашиваю ни одного сервера.Хранение ListView изображений в кеше

Когда я прокручиваю ListView, так как телефон должен отображать каждое изображение снова, иногда он немного замедляется, кажется низким fps. Для целей тестирования я использовал одинаковое изображение для всех элементов, а свиток был намного лучше, поэтому я думаю, что проблема в том, что на самом деле это разные изображения, необходимые для визуализации.

Мой вопрос: могу ли я хранить эти изображения в кеше или что-то, чтобы заставить этот свиток задушить? Вот мой 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; 
    } 
} 

ответ

1

Я полагаю, проблема в том, что вы разбираете JSON «на лету». Прежде всего разобрать JSON в список с объектами внутри AsyncTask, каждый объект будет содержать идентификатор, имя и растровое изображение.

Например:

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 или Пикассо, чтобы загрузить фотографии в фоновом режиме.

Просто замените эту строку на одну из этой библиотеки, а вместо этого растровое изображение сохраните drawable_id.

viewHolder.itemAvatar.setImageBitmap(itemAtPosition.bitmap);

Glide: 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

+0

Поскольку адаптер ожидает список теперь вместо Os в JSON массив, им не уверен, как работает эта линия: @Override общественность давно getItemId (целое положение) { возврата yourObjectsList.get (положение) .id; } У меня здесь ошибка. – Ravers

+0

Описание ошибки. –

+0

Извините, ошибка: «Невозможно разрешить символ« id »« – Ravers

Смежные вопросы