I am using a RecyclerView
to show a list in which each item contains text and images (I will search for the image from a url with the ImageLoader
in the method private void setImageNews(final ImageView view, String url)
). When loading the same, the images corresponding to each item are loaded correctly.
But when you scroll down and back up the images are loaded into the items that do not correspond or are not displayed.
My guess is that when you scroll and send to find the image of the corresponding item, when this item loses visibility due to the sliding of the list, the Bitmap
obtained from the Response
is loaded in the item that takes its place in that moment.
If so, what is the correct way to handle it or its solution ?, and if not,
What am I doing wrong?
In the onErrorResponse
hidden the RelativeLayout
that contains both the ImageView
and a ProgressBar
that is displayed while searching for the image.
public class MyAdapter extends RecyclerView.Adapter<MyAdapter .ViewHolder> {
private ArrayList<DtoNews> mData;
private Context mContext;
private View mView;
public MyAdapter() {
mData = new ArrayList();
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
mContext = parent.getContext();
mView = LayoutInflater.from(mContext)
.inflate(R.layout.item_news, parent, false);
return new ViewHolder(mView);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
final DtoNews news = mData.get(position);
holder.mMessageTitle.setText(news.getmUserName());
if(!news.getmImageUrl().equals("null"))
setImageNews(holder.mImageNews, news.getmImageUrl());
else
((RelativeLayout) mView.findViewById(R.id.relative_image)).setVisibility(GONE);
holder.mTextLike.setText("" + news.getmLikes());
holder.mLike.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
holder.mMessageDescription.setText(news.getmDescription());
}
@Override
public int getItemCount() {
return mData.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public final View mView;
public final TextViewSansPro mMessageTitle;
public final TextViewSansPro mMessageDescription;
public final TextViewSansPro mTextLike;
public final ImageView mImageNews;
public final ImageView mLike;
public ViewHolder(View view) {
super(view);
mView = view;
mMessageTitle = (TextViewSansPro) view.findViewById(R.id.publisher_name);
mMessageDescription = (TextViewSansPro) view.findViewById(R.id.text_noticia);
mTextLike = (TextViewSansPro) view.findViewById(R.id.text_like);
mImageNews = (ImageView) view.findViewById(R.id.image_news);
mLike = (ImageView) view.findViewById(R.id.like_icon);
}
@Override
public String toString() {
return super.toString() + " '" + mMessageDescription.getText() + "'";
}
}
public void setData(ArrayList<DtoNews> data, boolean isRefresh){
if(isRefresh) {
mData.clear();
mData.addAll(data);
notifyDataSetChanged();
}
else{
mData.addAll(data);
notifyItemRangeInserted(mData.size() - 1, mData.size() - 1 + data.size());
}
}
private void setImageNews(final ImageView view, String url){
NetworkCacheSingleton.getImageLoader().get(url, new ImageLoader.ImageListener() {
@Override
public void onResponse(final ImageLoader.ImageContainer response, boolean isImmediate) {
view.setImageBitmap(response.getBitmap());
}
@Override
public void onErrorResponse(VolleyError error) {
((RelativeLayout) mView.findViewById(R.id.relative_image)).setVisibility(GONE);
}
});
}
public ArrayList<DtoNews> getmData() {
return mData;
}
}
A little more information, this list works with paging:
For the 1st time the service returns the 1st 5 items that I am going to show and I call public void setData(ArrayList<DtoNews> data, boolean isRefresh)
to save them in ArrayList<DtoNews>
. Once in the list scrolling down I call the same service which returns me the following 5 that I am entering within the ArrayList
following the data that were already. So on until you get more data and have the complete list.
I clarify that the data come to me correctly in the established order.