Picasso + convertView: what am I doing wrong here?
Asked Answered
P

6

13

This is my getView().

I am obviously doing something wrong here, because the FIRST item of my list always shows no picture.

The problem here is with the convertview because if I don't recycle it, there is no problem.

Please what am I doing wrong??

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if(convertView==null) //IF I DELETE THIS IF EVERYTHING OK!!!
    convertView = inflater.inflate(R.layout.square, null);
    ImageView image = (ImageView) convertView.findViewById(R.id.background_image);
    if (data.get(position).isFollowed()) {
        int approprieteimage = getApproppreiateImage(data.get(position));
        Picasso.with(context).load(approprieteimage).centerCrop().error(R.drawable.no_image_available).transform(new TealTransformation(context)).fit().into(image);
    } else {
        int approprieteimage = getApproppreiateImage(data.get(position));
        Picasso.with(context).load(approprieteimage).centerCrop().error(R.drawable.no_image_available).fit().into(image);

    }
    AbsListView.LayoutParams layoutParams = new AbsListView.LayoutParams(width / 2, width / 2);
    convertView.setLayoutParams(layoutParams);
    return convertView;
}
Parvati answered 14/7, 2015 at 13:4 Comment(5)
Would you test again but remove .centerCrop() and .fit() from your Picasso command. I believe it has something to do with Picasso needing a first layout to be able to execute those actions.Illogical
Also make sure approppreateimage has correct value for the first itemLdopa
@Illogical thanks Budius, I have tried as you suggested, no success :-(Parvati
If you remove Picasso to load image directly and left if (convertview=null) as it is , does the thing work ?Buonomo
Use a viewholder and then recycleProfuse
K
5

Hi Lisa Anne please try this

ViewHolder h; //declare viewholder global

Your get view with viewholder

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

        if (convertView == null) {
            convertView = inflater.inflate(R.layout.square, parent, false);
            h = new ViewHolder();
            h.image = (ImageView) convertView.findViewById(R.id.background_image);
            convertView.setTag(h);
        }else{
            h = (ViewHolder)convertView.getTag();
        }
        //display in log and check if the the url of image is here and live.
        Log.e("checking","image file name"+data.get(position))
    if (data.get(position).isFollowed()) {
        int approprieteimage = getApproppreiateImage(data.get(position));
        Picasso.with(context).load(approprieteimage).centerCrop().error(R.drawable.no_image_available).transform(new TealTransformation(context)).fit().into(h.image);
    } else {
        int approprieteimage = getApproppreiateImage(data.get(position));
        Picasso.with(context).load(approprieteimage).centerCrop().error(R.drawable.no_image_available).fit().into(h.image);

    }
    AbsListView.LayoutParams layoutParams = new AbsListView.LayoutParams(width / 2, width / 2);
    convertView.setLayoutParams(layoutParams);

    return convertView;
}

Viewholder class

static class ViewHolder {
     ImageView  image;
  }

Your code might call findViewById() frequently during the scrolling of ListView, which can slow down performance. Even when the Adapter returns an inflated view for recycling, you still need to look up the elements and update them. A way around repeated use of findViewById() is to use the "view holder" design pattern.

A ViewHolder object stores each of the component views inside the tag field of the Layout, so you can immediately access them without the need to look them up repeatedly.

View holder is very useful technique especially when displaying images. Android Developer documentation

after that please show me your log error.

Kristiekristien answered 21/7, 2015 at 5:22 Comment(1)
Why would it only affect the first item image? Technique is good but seems off topic here.Decapod
D
1

Why don't you just use the Holder pattern in your adapter?

if (convertView == null) {
   convertView = inflater.inflate(R.layout.square, null, false);
   holder = new Holder(convertView);
   convertView.setTag(holder);
}
else {
   holder = (Holder) convertView.getTag();
}

Create your holder like this (replace it with your views)

public static class Holder {
    private View row;
    private TextView title;

    public Holder(View row) {
       this.row = row;
    }

    public TextView getTitle() {
       if (title == null) {
          title = (TextView) row.findViewById(R.id.title);
       }
       return title;
    }
 }

You should be fine.

Dogmatism answered 20/7, 2015 at 13:20 Comment(0)
N
1

As I found in this link: picasso issue When recycle the view, you should call cancelRequest before load new request. So the code should be:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if(convertView==null) //IF I DELETE THIS IF EVERYTHING OK!!!
    convertView = inflater.inflate(R.layout.square, null);
    ImageView image = (ImageView) convertView.findViewById(R.id.background_image);
    Picasso.with(context).cancelRequest(image); // cancel old request
    if (data.get(position).isFollowed()) {
        int approprieteimage = getApproppreiateImage(data.get(position));
        Picasso.with(context).load(approprieteimage).centerCrop().error(R.drawable.no_image_available).transform(new TealTransformation(context)).fit().into(image);
    } else {
        int approprieteimage = getApproppreiateImage(data.get(position));
        Picasso.with(context).load(approprieteimage).centerCrop().error(R.drawable.no_image_available).fit().into(image);

    }
    AbsListView.LayoutParams layoutParams = new AbsListView.LayoutParams(width / 2, width / 2);
    convertView.setLayoutParams(layoutParams);
    return convertView;
}
Naxos answered 23/7, 2015 at 7:53 Comment(0)
P
0

convertView = inflater.inflate(R.layout.square,parent,false);

Pass parentView to your convertView.

Pitchfork answered 22/7, 2015 at 11:1 Comment(0)
H
0
    try this one:
    It is working smoothly for me:

    @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            if (convertView == null) {
                convertView = mInflater.inflate(R.layout.row_events, null);
                holder = new ViewHolder();
                holder.txtdName = (TextView) convertView
                        .findViewById(R.id.txtTitle);
                holder.txtdate = (TextView) convertView.findViewById(R.id.txtDate);

                holder.txtSubTitle = (TextView) convertView
                        .findViewById(R.id.txtSubtitle);
                holder.imgEvent = (ImageView) convertView
                        .findViewById(R.id.imgEvents);
                holder.imgArrow = (ImageView) convertView
                        .findViewById(R.id.imgArrow);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }

            try {
                holder.txtdName.setText(listd.get(position).getName());
                holder.txtdate.setText(Constants.dateFormat(listd.get(position)
                        .getStart_date()));
                holder.txtSubTitle.setText(listd.get(position).getDescription());
                holder.txtSubTitle.setTextColor(Color.GRAY);
                String imgUrl = listd.get(position).getImageUrl();
                // imageLoader.displayImage(imgUrl, holder.imgEvent, options);
                Picasso.with(context).load(imgUrl).into(holder.imgEvent);

return convertView;
Hipped answered 23/7, 2015 at 5:28 Comment(0)
I
-1

Try this

convertView = inflater.inflate(R.layout.square, parent, false);
Injun answered 23/7, 2015 at 11:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.