Reputation: 2514
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 = (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;
}
The debug log under the if statement only fires for users that really have a profile picture. (Users that don't have will get a value of None
).
However, some of the other list view items (that don't have a profile pic) also get the picture loaded.
Another useful fact (I think): The items that get the bug changes when scrolling up and down the list.
I'm not sure what I'm missing here.
Upvotes: 17
Views: 9319
Reputation: 4292
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.
Upvotes: 0
Reputation: 31
Please refer the following codes.First is my grid_row.xml file. It is grid items layout file
<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>
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.
*/
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;
}
}
I am sure that this will help definitely. Thanks NOSTRA for such a great library. Thumbs Up...!!! Happy Coding... :)
Upvotes: 0
Reputation: 13657
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.
Upvotes: 35
Reputation: 11469
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;
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;
}
Upvotes: -2