问题
I'm implementing an activity with recyclerview. I load all the contacts that I have in the phone (name and phone numbers). All looks ok, the problem is that when I do a scroll in the view, when I come back at the same contact this contact don't have the correct phone numbers. Is the only one that change. Name and contact phone are display correctly.
For example, one contact only have set Mobile phone. Looks ok when initialize, but if I do scroll and come back, the Home and Work are set with another numbers, and this user only have set Mobile phone
Some help will be apreciate!
This is my onBind method in the 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 have to be something with thit, but this is my select:
String select = "((" + ContactsContract.Contacts.DISPLAY_NAME + " NOTNULL) AND (" + ContactsContract.Contacts.HAS_PHONE_NUMBER + " != 0 ))";
回答1:
This happens because of the way RecyclerView
works, and has nothing to do with the way you are accessing the contact data. A RecyclerView
only creates a ViewHolder
for each of the views that will fit on screen at one time, then recycles those views when they are scrolled off screen. Then the new content for that view gets applied in onBindViewHolder()
.
Since you may have assigned text for the ViewHolder.textHomePhone
and ViewHolder.textWorkPhone
text views previously, when those view holders get recycled that text is still there. Therefore, if the new contact only has a mobile number, the text for the home number and work number will still be filled out by the previous contact occupying that ViewHolder
.
To fix this you need to check if the contact doesn't have a number of each type (mobile, home and work), and if so set the visibility of the corresponding TextView
to View.GONE
.
A simple way to do this would be to create three boolean values before your loop, then check them afterwards:
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);
}
回答2:
I think the problem is with the following line:
if (dataCursor.moveToFirst())
you move the data cursor to point to the first element in each call which is not necessary and this will undo the following line at the top of the function:
dataCursor.moveToPosition(position);
if you remove the if
statement, it should work fine
来源:https://stackoverflow.com/questions/38978923/recyclerview-change-the-value-of-my-phonenumber-in-contactscontract-when-scroll