studio squareup implement android listview android-listview picasso

android - squareup - Picasso carga imágenes en la vista de imagen incorrecta en un adaptador de lista



picasso kotlin (4)

Estoy cargando una imagen de un servidor a un elemento de vista de lista usando picasso como este:

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; }

El registro de depuración bajo la instrucción if solo se activa para los usuarios que realmente tienen una imagen de perfil. (Los usuarios que no tienen obtendrán un valor de None ).

Sin embargo, algunos de los otros elementos de la vista de lista (que no tienen una foto de perfil) también obtienen la imagen cargada.

Otro dato útil (creo): los elementos que reciben el error cambian cuando se desplaza hacia arriba y hacia abajo en la lista.

No estoy seguro de lo que me estoy perdiendo aquí.


Asegúrese de llamar a cancelRequest cada vez que esté a punto de usar Picasso en un getView () desde el adaptador.

// 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);

El motivo es que la vista que está reutilizando desde el parámetro convertView pertenece a una fila anterior que posiblemente ya estaba cargando Picasso para otra imagen.

Esto solo es realmente necesario cuando se utiliza convertView, si acaba de inflar un diseño nuevo, no será necesario ... pero puede llamar siempre para facilitar el código.


Consulte los siguientes códigos. Primero es mi archivo grid_row.xml. Es un archivo de diseño de elementos de cuadrícula

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

A continuación, siga adelante con la clase de adaptador para referencia.

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; } }

Estoy seguro de que esto ayudará definitivamente. Gracias NOSTRA por una gran biblioteca. Pulgares hacia arriba...!!! Codificación feliz ... :)


Creo que he estado en la misma situación. Sugiero utilizar el patrón ViewHolder para su adaptador.

Será algo como esto.

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; }


En tu método getView () cambia tu código de Picasso de esta manera:

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 }

Actualizado

Use el concepto Viewholder en su método getView (). Obtendrá su todo hecho con esto solamente.