简体   繁体   English

与RecyclerView一起使用时,毕加索图像错位问题

[英]Picasso image misplacement issue when using with RecyclerView

In my app, I'm showing the articles which are getting fetched from a webservice. 在我的应用程序中,我正在展示从Web服务中获取的文章。 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. 问题 - 在滚动RecyclerView时,我看到图像放错了位置。 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. 我知道它是RecyclerView重用xml项目布局,因此它产生了一个问题。 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. 我已经google了这个,并在stackoverflow上发现了一些帖子,但这没有帮助。 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. 谢谢。

Externally set the drawable because you are getting the imageview which has some drawable already attached to it. 外部设置drawable,因为你正在获得已经附加了一些drawable的imageview。 Imageview is not getting recreated so the previous image in the ImageView will be visible until you remove it. Imageview未重新创建,因此ImageView中的上一个图像将一直显示,直到您将其删除。

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

Use setTag in onBindViewHolder it will hold data and your images will not misplace. 在onBindViewHolder中使用setTag,它将保存数据,您的图像不会错位。

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

OR 要么

Maybe try your approach maybe it works 也许试试你的方法也许它有效

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

Your view is reused. 您的视图可以重复使用。

Call Picasso.with(imgImage.getContext()).cancelRequest(imgImage); 调用Picasso.with(imgImage.getContext()).cancelRequest(imgImage); to cancel any existing requests of your ImageView. 取消ImageView的任何现有请求。

Then you can load your image if article.getImage() != null and provide a fallback if your article image is null like imgImage.setImageDrawable(R.drawable.some_drawable); 然后你可以加载你的图像如果article.getImage() != null并提供一个后备,如果你的文章图像是空的像imgImage.setImageDrawable(R.drawable.some_drawable);

Also, it worked for me: 此外,它对我有用:

@Override
public long getItemId(int position) {
    return position;
}

@Override
public int getItemViewType(int position) {
   return position;
}

These methods are a cleaner approach to accessing the list's data. 这些方法是访问列表数据的更简洁方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用毕加索完成图像加载时,Android RecyclerView冻结 - Android RecyclerView freezes when image loading is done using Picasso 使用毕加索将图像从数据库加载到recyclerview - Loading image from database to recyclerview using picasso 在 Recyclerview 中使用 Picasso 获取图像时出错 - Error in using Picasso to fetch image in Recyclerview 如何使用毕加索在 RecyclerView 中设置图像 - how to set image in RecyclerView using Picasso 滚动 RecyclerView 时,Android Picasso 图像加载应用程序崩溃 - Android Picasso image loading app crash when scrolls the RecyclerView Picasso 加载图像,即使在 recyclerView 中的特定位置没有图像 url? - Picasso loads image, even when there is not image url at a specific position in recyclerView? 使用 Picasso 从 firebase 获取图像问题 - Fetching Image Issue from firebase using Picasso 使用Picasso从Firebase数据库无法在Recyclerview上加载图像 - Image doesn't loads on recyclerview from firebase database using picasso Recyclerview,otifyItemChanged()和毕加索加载的图像 - Recyclerview, otifyItemChanged() and image loaded by Picasso 使用毕加索将图像从RecyclerView发送到nextActivity到ImageView - Sending an Image from a RecyclerView to the nextActivity into an ImageView using Picasso
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM