2014-10-14 6 views
12

Я пытаюсь использовать библиотеку Picasso для загрузки внешних изображений в строки в ListView. У меня есть обычай ArrayAdapter следующим образом:Picasso загружается в неправильное изображение при использовании шаблона держателя вида

public class RevisedBusinessesAdapter extends ArrayAdapter<HashMap<String, String>> { 

    Context context; 
    int layoutResourceId; 
    ArrayList<HashMap<String, String>> data = null; 

    public RevisedBusinessesAdapter(Context context, int layoutResourceId, ArrayList<HashMap<String, String>> data) { 
     super(context, layoutResourceId, data); 
     this.layoutResourceId = layoutResourceId; 
     this.context = context; 
     this.data = data; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     View row = convertView; 
     RevisedBusinessHolder holder = null; 

     if (row == null) { 
      LayoutInflater inflater = ((Activity) context).getLayoutInflater(); 
      row = inflater.inflate(layoutResourceId, parent, false); 
      holder = new RevisedBusinessHolder(); 
      holder.ivLogo = (ImageView) row.findViewById(R.id.ivBusinessLogo); 
      row.setTag(holder); 
     } else { 
      holder = (RevisedBusinessHolder) row.getTag(); 
     } 

     HashMap<String, String> business = data.get(position); 

     String strLogoURL = business.get("logoURL"); 
     if (null != strLogoURL && !"".equals(strLogoURL)) { 
      Picasso.with(this.context).load(strLogoURL).into(holder.ivLogo);   
     } 

     return row; 
    } 

    static class RevisedBusinessHolder { 
     ImageView ivLogo; 
    } 
} 

где logoURL является URL для удаленно расположенным изображения; если не указано, ivBusinessLogo имеет локальный набор src, и это показано вместо этого. Когда я быстро прокручиваю, Пикассо загружает изображение в неправильное ImageView, и я заканчиваю его несколькими копиями в списке.

Ответ на вопрос this предлагает добавить

Picasso.with(context).cancelRequest(holder.ivLogo); 

до существующего вызова Пикассо, но это не имеет никакого значения. Если я удалю проверку row == null и всегда создаю новое представление, оно работает нормально. В полной версии этого, однако, есть также четыре текстовых изображения и пять других изображений (маленькие значки, загруженные из локальных ресурсов, а не через Picasso), которые необходимо обновлять в каждом getView.

Есть ли способ сделать эту работу с помощью шаблона View Holder, который рекомендует Android documentation?

+0

Вы должны добавить оператор еще после Picasso.with() нагрузок() в() заявление.. Добавьте 'else holder.ivLogo.setImageBitmap (null);' .' Или используйте растровое изображение с заполнителем. – greenapps

+0

@greenapps ivLogo имеет набор src в XML, поэтому у него уже есть местозаполнитель. –

+0

Этого недостаточно, поскольку переработанное представление будет содержать неправильное растровое изображение старой позиции. – greenapps

ответ

-1

Добавить инструкцию else после команды Picasso.with(). Load(). В(). Добавить else holder.ivLogo.setImageBitmap(null);. Или используйте растровое изображение заполнителя.

Увидев решение Octa George, лучше всегда выполнять holder.ivLogo.setImageBitmap(placeholderbitmap); перед вызовом в Пикассо. В противном случае, когда Пикассо «не спешит», вы сначала увидите неправильное переработанное изображение.

+1

Это не решит проблему. По-прежнему существует потенциал для отображения неправильного изображения, потому что Picasso не знает, что изображение было переработано. –

+0

@ Jake Нет причин, чтобы опросить ответ, если он не является полным. Это помогло значительно уменьшить проблему ОП, как вы можете прочитать в своих комментариях. И это было «приглашение». – greenapps

+6

Ответ неверен и содержит ту же ошибку, что и вопрос. В сегодняшнем безудержном процессе копирования/вставки я хочу убедиться, что никто не использует это решение. –

21

Вы всегда должны позвонить в Picasso, даже если ваш URL-адрес null. Таким образом, он знает, что изображение было переработано.

Удалить if заявление:

if (null != strLogoURL && !"".equals(strLogoURL)) { 

Вы должны также рассмотреть возможность использования шаблонного изображения или изображение ошибки, так что что-то будет отображаться, если нет URL.

Если вы настаиваете на сохранении if заявление (но вы не должны!), То нужно сказать, что Пикассо вид изображения возвращали по телефону cancelRequest:

Picasso.with(this.context).cancelRequest(holder.ivLogo); 
+7

Удаление оператора 'if' приведет к тому, что вы подадите Picasso в пустую строку' String', в результате чего 'IllegalArgumentException: Path не должно быть пустым. ', Я прав? –

+1

Джейк, ты даже не представлял, как это спасло этот день. Я пробовал много комбинаций отмены и приостановки тегов при событиях сбрасывания, но ничто не помогло, так как это cancelRequest в нужном месте. – miroslavign

+1

@ IvanMorgillo вправо, Джейк ошибся, но его точка зрения заключалась в том, что вы всегда должны позвонить Пикассо, и это, если бы статья не мешала ему. В любом случае, спасибо Джейку! –

0

У меня такая же проблема, и установил ее , Пожалуйста, подумайте о параметре convertView в методе getView

convertView - это старый вид для повторного использования, если это возможно. Примечание. Вы должны проверить , что перед просмотром это представление не является нулевым и соответствующего типа. Если невозможно преобразовать это представление, чтобы отобразить правильные данные, этот метод может создать новый вид.

При использовании держателя Picasso будет загружать изображение в образное изображение строки и повторное его использование. Вот почему вы видите дублирующее изображение. И, на мой взгляд, вы должны загрузить свое изображение, пока создается первый вид строки.Попробуйте изменить код

if (row == null) { 
    LayoutInflater inflater = ((Activity) context).getLayoutInflater(); 
    row = inflater.inflate(layoutResourceId, parent, false); 
    holder = new RevisedBusinessHolder(); 
    ImageVIew ivLogo = (ImageView) row.findViewById(R.id.ivBusinessLogo); 
    Picasso.with(this.context).load("Your Image URL").into(holder.ivLogo); 
    row.setTag(holder); 
} 
2

ГКЗА по умолчанию Drawable установлено в layout.xml (на ImageView) является неоспоримым переопределением последнего кэшированных Dowload изображения, если текущий элемент оленьей кожи есть изображение, которое будет скачать из URL ,

Вы должны вручную установить вытяжку по умолчанию для itens, что не имеют изображения atribute:.

try { 
    Picasso.with(activity.getApplicationContext()).load(customer.getImage().getPath()).placeholder(R.drawable.image_placeholder) 
       .error(R.drawable.image_placeholder).into(imageView); 
    } 
catch (Exception e) { 
     imageView.setImageResource(R.drawable.default_customer_icon); 
     // this set the default img source if the path provided in .load is null or some error happened on download. 
    }