Picasso загружает изображения в неправильное изображение в адаптере списка

Я загружаю изображение с сервера в элемент списка, используя picasso следующим образом:

public View getView(int position, View convertView, ViewGroup parent) { LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); View participantView; if(convertView == null) { participantView = inflater.inflate(R.layout.participant_item, parent, false); } else { participantView = convertView; } TextView textView = (TextView) participantView.findViewById(R.id.participantName); textView.setText(getItem(position).getName()); ImageView imageView = (ImageView) participantView.findViewById(R.id.participantImage); String profilePic = getItem(position).getProfilePic(); if(!profilePic.equals("None")) { Log.d("tom.debug", "creating picture for user: " + getItem(position).getName()); Picasso.with(this.context) .load(urlToProfilePics + profilePic) .placeholder(R.drawable.sample_0) .resize(52, 52) .into(imageView); } else { //load the place holder into the image view Picasso.with(this.context).load(R.drawable.sample_0); } if(!getItem(position).isHere()) { imageView.setColorFilter(Color.DKGRAY, PorterDuff.Mode.MULTIPLY); } return participantView; } 

Журнал отладки под оператором if запускается только для пользователей, у которых действительно есть профиль. (Пользователи, у которых их нет, получат значение None ).

Тем не менее, некоторые из других элементов просмотра списка (которые не имеют профиля pic) также загружают изображение.

Другой полезный факт (я думаю): элементы, которые получают ошибку, изменяются при прокрутке вверх и вниз по списку.

Я не уверен, что мне здесь не хватает.

Solutions Collecting From Web of "Picasso загружает изображения в неправильное изображение в адаптере списка"

Убедитесь, что вы вызываете cancelRequest каждый раз, когда собираетесь использовать Picasso в getView () из адаптера.

 // 1st: reset the imageView Picasso.with(this.context).cancelRequest(holder.imageView); // 2nd start a new load for the imageView Picasso.with(this.context).load(...).into(holder.imageView); 

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

Это действительно необходимо при использовании convertView, если вы только что запустили новый макет, он не понадобится … но вы можете всегда звонить, чтобы сделать ваш код проще.

Пожалуйста, обратитесь к следующим кодам. Сначала мой файл grid_row.xml. Это файл макета элементов сетки

 <ProgressBar android:layout_height="70dp" android:layout_width="70dp" android:id="@+id/myprogress" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_below="@+id/title" /> <View android:layout_width="2dp" android:layout_height="2dp"/> <ImageView android:layout_height="165dp" android:id="@+id/imageView1" android:layout_width="125dp" android:scaleType="fitXY" android:layout_alignParentTop="true" android:layout_centerHorizontal="true"/> <View android:layout_width="2dp" android:layout_height="2dp"/> <TextView android:text="TextView" android:layout_height="wrap_content" android:id="@+id/title" android:layout_width="wrap_content" android:layout_below="@+id/imageView1" android:textStyle="bold" android:layout_marginTop="2dp" android:layout_centerHorizontal="true" android:textSize="20sp" android:ellipsize="marquee"> </TextView> <View android:layout_width="2dp" android:layout_height="2dp"/> <TextView android:text="TextView" android:layout_height="wrap_content" android:id="@+id/subTitle" android:layout_width="wrap_content" android:layout_below="@+id/title" android:layout_marginTop="2dp" android:layout_centerHorizontal="true" android:textSize="18sp" android:ellipsize="marquee"> </TextView> </RelativeLayout> 

Затем, пожалуйста, обратитесь к классу адаптеров для справки.

 import android.app.Activity; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; import com.nostra13.universalimageloader.core.assist.FailReason; import com.nostra13.universalimageloader.core.assist.ImageScaleType; import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer; import com.nostra13.universalimageloader.core.listener.ImageLoadingListener; import com.nostra13.universalimageloader.core.listener.ImageLoadingProgressListener; import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener; import com.squareup.picasso.Picasso; import java.util.ArrayList; /** * Created by mpatil on 28/05/15. */ public class GridViewAdapter extends BaseAdapter { private ArrayList<String> listTitle; private ArrayList<String> listSubTitle; private ArrayList<String> imgp; private Context activity; ViewHolder view; Configuration_Parameter m_config=Configuration_Parameter.getInstance(); public GridViewAdapter(Context activity,ArrayList<String> listTitle, ArrayList<String> subTitle,ArrayList<String> img) { super(); this.listTitle = listTitle; this.imgp = img; this.listSubTitle=subTitle; this.activity = activity; } @Override public int getCount() { // TODO Auto-generated method stub return listTitle.size(); } @Override public String getItem(int position) { // TODO Auto-generated method stub return (String) (String) view.imgViewFlag.getTag(); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return 0; } public static class ViewHolder { public ImageView imgViewFlag; public TextView txtViewTitle; public TextView txtViewSubTitle; public ProgressBar pg; public ViewHolder(View v) { } public ViewHolder() { } } @Override public View getView(final int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub View participentView=convertView; if(participentView == null || participentView.getTag() == null) { LayoutInflater inflater = null; inflater=(LayoutInflater) parent.getContext().getSystemService(activity.LAYOUT_INFLATER_SERVICE); view = new ViewHolder(); participentView = inflater.inflate(R.layout.grid_layout, null); view.txtViewTitle = (TextView) participentView.findViewById(R.id.title); view.txtViewSubTitle = (TextView) participentView.findViewById(R.id.subTitle); view.pg=(ProgressBar)participentView.findViewById(R.id.myprogress); view.imgViewFlag = (ImageView) participentView.findViewById(R.id.imageView1); participentView.setTag(view); } else { view = (ViewHolder) participentView.getTag(); } //download and display image from url view.txtViewTitle.setText(listTitle.get(position)); view.txtViewSubTitle.setText(listSubTitle.get(position) + " subitem"); ImageLoader imageLoader = null; imageLoader= ImageLoader.getInstance(); DisplayImageOptions options = new DisplayImageOptions.Builder() .showImageForEmptyUri(R.drawable.paceholder) // resource or drawable .showImageOnFail(R.drawable.error_page_logo) // resource or drawable .resetViewBeforeLoading(false) // default .delayBeforeLoading(1000) .cacheInMemory(true) // default .cacheOnDisk(true) // default .build(); m_config.imageLoader.displayImage(imgp.get(position), view.imgViewFlag,options,new SimpleImageLoadingListener() { @Override public void onLoadingStarted(String imageUri, View v) { Log.i("Inside onLoadingStarted " + position,"Yes"); view.imgViewFlag.setVisibility(View.INVISIBLE); view.pg.setVisibility(View.VISIBLE); view.imgViewFlag.setVisibility(View.INVISIBLE); } @Override public void onLoadingFailed(String imageUri, View v, FailReason failReason) { Log.i("Inside onLoadingFailed " + position,"Yes"); view.pg.setVisibility(View.GONE); } @Override public void onLoadingComplete(String imageUri, View v, Bitmap loadedImage) { Log.i("Ins onLoadingComplete " + position, "Yes"); view.pg.setVisibility(View.GONE); view.imgViewFlag.setVisibility(View.VISIBLE); view.imgViewFlag.invalidate(); } }); return participentView; } } 

Я уверен, что это поможет. Спасибо NOSTRA за такую ​​замечательную библиотеку. Пальцы вверх…!!! Счастливое кодирование … 🙂

В вашем методе getView () измените код Picasso следующим образом:

  try { Picasso.with(mActivity). cancelRequest(holder.mImgCity); Picasso.with(mActivity). load(getItem(position).getBackgroundImg()). error(R.drawable.image_1). into(holder.mImgCity); } catch (IllegalArgumentException e) { e.printStackTrace(); holder.mImgCity.setImageResource(R.drawable.image_1); //<-- Important line } 

обновленный

Используйте концепцию Viewholder в методе getView (). Вы получите все, что с этим связано.

Я думаю, что я был в той же ситуации. Я предлагаю использовать шаблон ViewHolder для вашего адаптера.

Это будет что-то вроде этого.

 public View getView(int position, View convertView, ViewGroup parent) { final ViewHolder holder; View participantView = convertView; if (participantView == null || participantView.getTag() == null) { LayoutInflater inflater = (LayoutInflater) mContext .getSystemService(Context.LAYOUT_INFLATER_SERVICE); // don't forget to inflate the same layout participantView = inflater.inflate(R.layout.participant_item, null); holder = getHolder(participantView); assert participantView != null; participantView.setTag(holder); } else { holder = (ViewHolder) participantView.getTag(); } holder.textView.setText(getItem(position).getName()); String profilePic = getItem(position).getProfilePic(); if(!profilePic.equals("None")) { Log.d("tom.debug", "creating picture for user: " + getItem(position).getName()); Picasso.with(this.context) .load(urlToProfilePics + profilePic) .placeholder(R.drawable.sample_0) .resize(52, 52) .into(holder.imageView); } else { //load the place holder into the image view Picasso.with(this.context).load(R.drawable.sample_0); } if(!getItem(position).isHere()) { holder.imageView.setColorFilter(Color.DKGRAY, PorterDuff.Mode.MULTIPLY); } resetViews(participantView); return participantView; } void resetViews(View v) { ViewHolder mHolder = new ViewHolder(v); mHolder.textView.invalidate(); mHolder.imageView.invalidate(); } static class ViewHolder { TextView textView; ImageView imageView; }