[英]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.