在我的应用中,我展示了从网络服务中获取的文章。那些文章有标题,图像和其他领域。为了显示图像,我使用Picasso。
问题 - 在滚动RecyclerView时,我发现图像放错了位置。有些项目有重复的图像。我知道它是RecyclerView重用xml项目布局,因此它产生了一个问题。但我认为必须解决这个问题。我已经搜索过这个并在stackoverflow上发现了一些帖子,但这并没有帮助。例如 -
Picasso loads pictures to the wrong imageview in a list adapter
我已经尝试了以下但遇到同样的问题 -
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);
}
});
}
}
}
更新 - 部分布局文件
<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"
/>
任何帮助将不胜感激。谢谢。
答案 0 :(得分:8)
外部设置drawable,因为你得到的imageview已经附加了一些drawable。 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);
}
答案 1 :(得分:1)
在onBindViewHolder中使用setTag,它将保存数据,您的图像不会错位。
@Override
public void onBindViewHolder(ArticleViewHolder holder, int position) {
holder.bind(mItems.get(position));
holder.imgImage.setTag(mItems.get(position));
}
OR
也许尝试一下你的方法可能有效
@Override
public void onBindViewHolder(ArticleViewHolder holder, int position) {
holder.bind.setTag(mItems.get(position));
}
答案 2 :(得分:0)
您的观点会被重复使用。
调用Picasso.with(imgImage.getContext()).cancelRequest(imgImage);
取消ImageView的所有现有请求。
然后,您可以加载article.getImage() != null
的图片,如果您的文章图片为空imgImage.setImageDrawable(R.drawable.some_drawable);
答案 3 :(得分:0)
它也对我有用:
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemViewType(int position) {
return position;
}
这些方法是一种访问列表数据的更干净的方法。