Recyclerview changes the value of my phone number in contacts. Contract while scrolling through the list

I operate with recyclerview. I download all the contacts that I have on my phone (name and phone numbers). Everything looks fine, the problem is that when I spend the scroll in the view, when I return to the same contact, this contact does not have the correct phone numbers. The only thing that is changing. The name and contact phone number are displayed correctly.

For example, one contact just set up a mobile phone. It looks fine when initialized, but if I scroll and return, Home and Work are set with different numbers, and this user has set up only a mobile phone

Some help would be helpful!

This is my onBind method in recyclerAdapter:

@Override public void onBindViewHolder(ViewHolder holder, int position) { dataCursor.moveToPosition(position); holder.mTextView.setText((dataCursor.getString(1))); ContentResolver cr = context.getContentResolver(); String contactId = dataCursor.getString(dataCursor.getColumnIndex(ContactsContract.Contacts._ID)); Long photoTest = dataCursor.getLong(dataCursor.getColumnIndex(ContactsContract.Contacts.PHOTO_ID)); if (dataCursor.moveToFirst()) { Cursor phones = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactId, null, null); if (phones == null) { phones.close(); } else { while (phones.moveToNext()) { try { Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?", new String[]{contactId}, null); while (pCur.moveToNext()) { int phoneType = pCur.getInt(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE)); String phoneNumber = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); if(phoneType == TYPE_MOBILE){ holder.mNumberMoBilePhone.setText(phoneNumber); holder.mNumberMoBilePhone.setVisibility(View.VISIBLE); holder.textMobilePhone.setVisibility(View.VISIBLE); }else if(phoneType == TYPE_HOME){ holder.mNumberHomePhone.setText(phoneNumber); holder.mNumberHomePhone.setVisibility(View.VISIBLE); holder.textHomePhone.setVisibility(View.VISIBLE); }else if(phoneType == TYPE_WORK){ holder.mNumberWorkPhone.setText(phoneNumber); holder.mNumberWorkPhone.setVisibility(View.VISIBLE); holder.textWorkPhone.setVisibility(View.VISIBLE); }else{} } } catch (NullPointerException n) { } } phones.close(); } } if (photoTest != null) { ContactPhotoLoaderSdk5.instance().loadPhoto(holder.mContactPhoto, photoTest); } } 

Not sure if there should be anything with this, but this is my choice:

 String select = "((" + ContactsContract.Contacts.DISPLAY_NAME + " NOTNULL) AND (" + ContactsContract.Contacts.HAS_PHONE_NUMBER + " != 0 ))"; 
0
android android-recyclerview
Aug 16 '16 at 15:30
source share
2 answers

This is due to how the RecyclerView works, and has nothing to do with how you access the contact information. A RecyclerView only creates a ViewHolder for each of the views that will fit on the screen at a time, and then processes those views when they scroll from the screen. Then, the new content for this view is applied in onBindViewHolder() .

Since you may have previously assigned text for the text views ViewHolder.textHomePhone and ViewHolder.textWorkPhone when these view holders are returned, this text still exists. Therefore, if a new contact has only a mobile phone number, the text for the home number and work number will still be filled in with the previous contact holding this ViewHolder value.

To fix this, you need to check if each contact has a contact (mobile, home and work), and if so, set the visibility of the corresponding TextView to View.GONE .

An easy way to do this is to create three Boolean values ​​before your loop, and then check them:

 boolean hasMobile = false; boolean hasHome = false; boolean hasWork = false; while (pCur.moveToNext()) { int phoneType = pCur.getInt(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE)); String phoneNumber = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); if(phoneType == TYPE_MOBILE){ holder.mNumberMoBilePhone.setText(phoneNumber); holder.mNumberMoBilePhone.setVisibility(View.VISIBLE); holder.textMobilePhone.setVisibility(View.VISIBLE); hasMobile = true; }else if(phoneType == TYPE_HOME){ holder.mNumberHomePhone.setText(phoneNumber); holder.mNumberHomePhone.setVisibility(View.VISIBLE); holder.textHomePhone.setVisibility(View.VISIBLE); hasHome = true; }else if(phoneType == TYPE_WORK){ holder.mNumberWorkPhone.setText(phoneNumber); holder.mNumberWorkPhone.setVisibility(View.VISIBLE); holder.textWorkPhone.setVisibility(View.VISIBLE); hasWork = true; } } if(!hasMobile) { holder.mNumberMobilePhone.setVisibility(View.GONE); holder.textMobilePhone.setVisibility(View.GONE); } if(!hasHome) { holder.mNumberHomePhone.setVisibility(View.GONE); holder.textHomePhone.setVisibility(View.GONE); } if(!hasWork) { holder.mNumberWorkPhone.setVisibility(View.GONE); holder.textWorkPhone.setVisibility(View.GONE); } 
+1
Aug 16 '16 at 15:57
source share

I think the problem is with the following line:

 if (dataCursor.moveToFirst()) 

you move the data cursor to indicate the first element in every call that is not needed, and this will cancel the next line at the top of the function:

 dataCursor.moveToPosition(position); 

if you delete the if it should work fine

0
Aug 16 '16 at 16:04
source share



All Articles