Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Picasso image misplacement issue when using with RecyclerView

In my app, I'm showing the articles which are getting fetched from a webservice. Those articles have title, image and other fields. For displaying the images, I'm using Picasso.

Problem - While scrolling the RecyclerView, I'm seeing the images getting misplaced. Some items are having the duplicate images. I know it is RecyclerView which reuses the xml item layout and because of that it is creating a problem. But I think there must be some solution to this problem. I've googled about this and found some posts on stackoverflow but that didn't help. For example-

Picasso loads pictures to the wrong imageview in a list adapter

I've tried the following but having the same problem-

public class ArticleAdapter extends RecyclerView.Adapter<ArticleAdapter.ArticleViewHolder> {

    protected Activity mActivity;
    protected List<Article> mItems = new ArrayList<>();
    private static OnEntityClickCallback mCallback;

    public ArticleAdapter(Activity pActivity) {
        mActivity = pActivity;
    }

    public void setItemClickCallback(OnEntityClickCallback pCallback) {
        this.mCallback = pCallback;
    }

    @Override
public ArticleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View articleView = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_article_item, parent, false);
    return new ArticleViewHolder(articleView);
}

    public void addItem(List<Article> moreItems) {
        mItems.addAll(moreItems);
        notifyDataSetChanged();
    }

    public void removeItems(){
        mItems.clear();
        notifyDataSetChanged();
    }


    @Override
    public void onBindViewHolder(ArticleViewHolder holder, int position) {
        holder.bind(mItems.get(position));
    }

    @Override
    public int getItemCount() {
        return mItems.size();
    }


    static class ArticleViewHolder extends RecyclerView.ViewHolder {

        private TextView tvTitle;
        TextView tvAuthor;
        TextView tvPostdate;
        ImageView imgImage;
        RatingBar ratingBar;

        public ArticleViewHolder(View view) {
            super(view);
            this.tvTitle = (TextView) view.findViewById(R.id.tv_title);
            this.tvAuthor = (TextView) view.findViewById(R.id.tv_author);
            this.tvPostdate = (TextView) view.findViewById(R.id.tv_date);
            this.imgImage = (ImageView) view.findViewById(R.id.img_image);
            this.ratingBar = (RatingBar) view.findViewById(R.id.ratingBar);
        }

       public void bind(final Article article) {

        tvTitle.setText(article.getTitle());
        tvPostdate.setText(article.getPostdate());
        tvAuthor.setText(article.getAuthor());

        // Canceling the older request
        Picasso.with(imgImage.getContext()).cancelRequest(imgImage);
         // Creating a new request.
        if (article.getImage() != null) {
                Picasso.with(imgImage.getContext()).load(article.getImageUrl())
                .placeholder(R.drawable.noimage)
                .error(R.drawable.noimage)
                .into(imgImage);
        }

    this.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (mCallback != null)
                mCallback.onEntitySelected(article);
        }
    });
}

    }
}

Update - Part of my layout file

 <ImageView
                    android:id="@+id/img_image"
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/cardview_image_thumbnail_height"
                    android:layout_alignParentStart="true"
                    android:layout_alignParentLeft="true"
                    android:scaleType="centerCrop"
                    android:layout_margin="@dimen/cardview_padding_btw_widgets"
                    android:src="@drawable/noimage"
                    />

Any help would be appreciated. Thank you.

like image 691
Rahul Chaurasia Avatar asked Dec 29 '15 06:12

Rahul Chaurasia


1 Answers

Externally set the drawable because you are getting the imageview which has some drawable already attached to it. Imageview is not getting recreated so the previous image in the ImageView will be visible until you remove it.

    if (article.getImage() != null) {
            Picasso.with(imgImage.getContext()).load(article.getImageUrl())
                    .placeholder(R.drawable.noimage)
                    .error(R.drawable.noimage)
                    .into(imgImage);
    }else{
//         imgImage.setImageDrawable(null);
         imgImage.setImageDrawable(R.drawable.some_drawable);
    }
like image 174
Ankit Aggarwal Avatar answered Oct 13 '22 08:10

Ankit Aggarwal