Skip to content Skip to sidebar Skip to footer

Picasso Loads Pictures To The Wrong Imageview In A List Adapter

I'm loading an image from a server to a list view item using picasso like this: public View getView(int position, View convertView, ViewGroup parent) { LayoutInflater inflater

Solution 1:

Make sure you call the cancelRequest everytime you are about to use Picasso on a getView() from the Adapter..

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

The reason is that the view you are reusing from the convertView parameter belongs to a previous row that was possibly already being loaded by Picasso for another picture.

This is only really necessary when using the convertView, if you have just inflated a new layout, it won't be needed..but you can call always to make your code easier.

Solution 2:

Please refer the following codes.First is my grid_row.xml file. It is grid items layout file

<ProgressBarandroid:layout_height="70dp"android:layout_width="70dp"android:id="@+id/myprogress"android:layout_alignParentTop="true"android:layout_centerHorizontal="true"android:layout_below="@+id/title"       /><Viewandroid:layout_width="2dp"android:layout_height="2dp"/><ImageViewandroid:layout_height="165dp"android:id="@+id/imageView1"android:layout_width="125dp"android:scaleType="fitXY"android:layout_alignParentTop="true"android:layout_centerHorizontal="true"/><Viewandroid:layout_width="2dp"android:layout_height="2dp"/><TextViewandroid: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><Viewandroid:layout_width="2dp"android:layout_height="2dp"/><TextViewandroid: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>

Then Please go ahead with the adapter class for reference.

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.
 */publicclassGridViewAdapterextendsBaseAdapter
{
private ArrayList<String> listTitle;
private ArrayList<String> listSubTitle;
private ArrayList<String> imgp;

private Context activity;
ViewHolder view;
Configuration_Parameter m_config=Configuration_Parameter.getInstance();

publicGridViewAdapter(Context activity,ArrayList<String> listTitle, ArrayList<String> subTitle,ArrayList<String> img)
{
    super();
    this.listTitle = listTitle;
    this.imgp = img;
    this.listSubTitle=subTitle;
    this.activity = activity;


}

@OverridepublicintgetCount()
{
    // TODO Auto-generated method stubreturn listTitle.size();
}

@Overridepublic String getItem(int position)
{
    // TODO Auto-generated method stubreturn (String) (String) view.imgViewFlag.getTag();
}


@OverridepubliclonggetItemId(int position)
{
    // TODO Auto-generated method stubreturn0;
}

publicstaticclassViewHolder
{
    public ImageView imgViewFlag;
    public TextView txtViewTitle;
    public TextView txtViewSubTitle;
    public ProgressBar pg;

    publicViewHolder(View v)
    {

    }
    publicViewHolder()
    {
    }
}

@Overridepublic View getView(finalint position, View convertView, ViewGroup parent)
{
    // TODO Auto-generated method stub
    View participentView=convertView;

    if(participentView == null || participentView.getTag() == null)
    {
        LayoutInflaterinflater=null;
        inflater=(LayoutInflater) parent.getContext().getSystemService(activity.LAYOUT_INFLATER_SERVICE);
        view = newViewHolder();
        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");
    ImageLoaderimageLoader=null;
    imageLoader= ImageLoader.getInstance();

    DisplayImageOptionsoptions=newDisplayImageOptions.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,newSimpleImageLoadingListener()
    {
        @OverridepublicvoidonLoadingStarted(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);
        }
        @OverridepublicvoidonLoadingFailed(String imageUri, View v, FailReason failReason)
        {
            Log.i("Inside onLoadingFailed " + position,"Yes");
            view.pg.setVisibility(View.GONE);

        }
        @OverridepublicvoidonLoadingComplete(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;
 }

 }

I am sure that this will help definitely. Thanks NOSTRA for such a great library. Thumbs Up...!!! Happy Coding... :)

Solution 3:

In your getView() method change your Picasso code like this:

        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
            }

Updated

Use Viewholder concept in your getView() method. You will get your everything done with this only.

Solution 4:

I think I've been into the same situation. I suggest to use ViewHolder pattern for your adapter.

It will be something like this.

public View getView(int position, View convertView, ViewGroup parent) {

    final ViewHolder holder;
    ViewparticipantView= convertView;
    if (participantView == null || participantView.getTag() == null) {
        LayoutInflaterinflater= (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());
    StringprofilePic= 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;
}

voidresetViews(View v) {
    ViewHoldermHolder=newViewHolder(v);
    mHolder.textView.invalidate();
    mHolder.imageView.invalidate();
}

staticclassViewHolder { 
  TextView textView;
  ImageView imageView;
} 

Post a Comment for "Picasso Loads Pictures To The Wrong Imageview In A List Adapter"