How to prevent RecyclerView reuse of elements of the list?

The application uses recyclerwiew to display your contacts list. In the old version of the application once and for all life rocked 300MB users ' photos, and then in OnBindViewHolder just got it from the database. No problems in the display (in recyclerview) did not arise.
Now photos are downloaded from the network as needed to display them (of course asynchronously), are recorded in the database and the result is displayed in the right itime. Everything looks fine but as soon as there is a scroll list of contacts, their photos are duplicated and only when scroll stop, they disappear, re-created already displayed correctly. That is, recyclerview in the moment stop blinking like a Christmas tree. It is clear that this comes from the fact that the recyclerview visible preispolitik itemview. The problem is solved, if you switch from listview to recyclerview and be sure to set him setHasFixedSize(true). However, I just need to use a recyclerview, not the listview.

Code of adapter:

@Override
public void onBindViewHolderCursor(ContactViewHolder holder, Cursor cursor) {

 String firstName = cursor.getString(cursor.getColumnIndex(DatabaseSchemas.Profile.FIRST_NAME));
 String lastName = cursor.getString(cursor.getColumnIndex(DatabaseSchemas.Profile.LAST_NAME));
 holder.mName.setText(String.format("%s %s", lastName, firstName));

 profileid as long = cursor.getInt(cursor.getColumnIndex(DatabaseSchemas.Profile.ID));
 boolean gender = cursor.getString(cursor.getColumnIndex(DatabaseSchemas.Profile.SEX)).equals("M");
 holder.mPhoto.setEmploeePhoto(call mcontext, profileid as age, gender, holder.mPhoto);
 //NOTE below the old method of displaying images, which works without problems
 //ImageUtils.displayUserPhoto(call mcontext, profileid as age, gender, holder.mPhoto);

holder.setHighlightQuery(mQuery);
}


Now in detail about the new method holder.mPhoto.setEmploeePhoto, which either shows the image from the database, or shakes from the network, saves to the DB and shows.

public void setEmploeePhoto(final Context Context, final long mEmployee_id, final boolean gender, final ImageView imageView) {

 if (ImageUtils.userPhotoIsExist(context, mEmployee_id)){

 ImageUtils.displayUserPhoto(context, mEmployee_id, gender, imageView);
//NOTE that this is the method of displaying a photo 
//which was commented out in OnBindViewHolder, 
//and below that, it is used again after the download and save it into the database. 
//But only while he was working in OnBindViewHolder, the photo is perfectly visible when scrolling, 
//and here there is a problem with duplication and comparison is a Christmas tree

}
 else {

 JSONObject filter = new JSONObject();
 JSONArray values = new JSONArray();
values.put(String.valueOf(mEmployee_id));
 try {
 filter.put("values", values);
 filter.put("field", "user_id");
 } catch (JSONException e) {
e.printStackTrace();
return;
}
 new SapApi(getContext()).getPhoto(filter)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
 .subscribe(new Action1<inputstream>() {
@Override
 public void call(final InputStream inputStream) {
//If the photo is successfully downloaded from the network
 new LoadAndWritePhoto(context,mEmployee_id, gender, imageView, inputStream).execute();

}
 }, new Action1<throwable>() {
@Override
 public void call(Throwable throwable) {
 Toast.makeText(getContext(), throwable.getMessage(), Toast.LENGTH_LONG).show();
}
});

}

}

public class LoadAndWritePhoto extends AsyncTask<void, void, void> {//Because data cannot be written to the database in the main thread
 Context mmContext;
 profileid as long;
 boolean gender;
 ImageView mImageView;
 InputStream inputStream;

 public LoadAndWritePhoto(Context mmContext, profileid as long, boolean gender, ImageView mImageView, InputStream inputStream) {
 this.mmContext = mmContext;
 this.profileid as = profileid as;
 this.gender = gender;
 this.mImageView = mImageView;
 this.inputStream = inputStream;
}

@Override
 protected void for the onpreexecute() {
super.for the onpreexecute();
}

@Override
 protected Void doInBackground(Void... params) {//logic background
{
 try {
 PhotosSdCardWriter.writePhotosFromJson(mmContext, inputStream);
 } catch (Exception e){
e.printStackTrace();
}
}
 return null;
}

@Override
 protected void onProgressUpdate(Void... values) {//update the interface until the completion of the stream (not required)
super.onProgressUpdate(values);
}

@Override
 protected void onPostExecute(Void aVoid) {//result background logic
super.onPostExecute(aVoid);
 try {
 ImageUtils.displayUserPhoto(mmContext, profileid as age, gender, mImageView);
 }catch (Exception e){
e.printStackTrace();
}
}
}</void></throwable></inputstream>
July 2nd 19 at 18:03
1 answer
July 2nd 19 at 18:05
This is fundamentally the wrong approach. The meaning recycler it is in use. You need to change the way of dealing with pictures, you have it spelled wrong. Take any popular library type Glide or Picasso - with their use will not be such problems.
I have already used these libraries to solve this same problem, but there was no difference. Is there any other way? - Allene.Lemke28 commented on July 2nd 19 at 18:08
do not care what libo use, but it is better to use, because it performs caching. Just simply in onBind clean an old photo provided by the library methods. For example frescolib it setController(null) for the old controller - Rocio_Cruicksha commented on July 2nd 19 at 18:11

Find more questions by tags Android