Recyclerview change the value of my phoneNumber in contactsContract when scroll the view

主宰稳场 提交于 2019-12-12 02:25:42

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!