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.