2016-08-16 65 views
0

我正在使用recyclerview实施一项活动。我加载了手机中的所有联系人(姓名和电话号码)。一切看起来都不错,问题是当我在视图中进行滚动时,当我回到同一联系人时,此联系人没有正确的电话号码。是唯一一个改变。姓名和联系电话显示正确。Recyclerview在滚动视图时更改contactsContract中phoneNumber的值

例如,一个联系人只设置了手机。初始化时看起来没问题,但如果我滚动并回来,家庭和工作设置了另一个数字,并且此用户只有设置移动电话

一些帮助将apreciate!

这是我在recyclerAdapter onBind方法:

@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); 
      } 

    } 

不知道是否必须与thit东西,但这是我的选择:

String select = "((" + ContactsContract.Contacts.DISPLAY_NAME + " NOTNULL) AND (" + ContactsContract.Contacts.HAS_PHONE_NUMBER + " != 0))"; 
+0

我建议您在设置适配器时从数据库获取所有数据。将这些数据放入一个列表中并使用适配器中的列表。这样可以提高性能,使代码更清晰,并且更容易发现错误。 – Robbe

回答

1

出现这种情况,因为方式RecyclerView工作,并且与您访问联系人数据的方式无关。 A RecyclerView仅针对每次适合在屏幕上显示的每个视图创建一个ViewHolder,然后将这些视图在屏幕滚动时回收。然后,该视图的新内容将在onBindViewHolder()中应用。

既然你以前可能分配的文本为ViewHolder.textHomePhoneViewHolder.textWorkPhone文本视图,当这些观点持有者得到回收的文本仍然存在。因此,如果新联系人只有一个手机号码,则家庭号码和工作号码的文本仍将由先前联系人填写ViewHolder

要解决这个问题,你需要检查是否接触有一些每种类型(移动,家庭和工作)的,如果是这样设置相应TextView的知名度,View.GONE

一个简单的方法来做到这将是你的循环之前,创建三个布尔值,然后事后检查他们:

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); 
} 
0

我认为这个问题是与以下行:

if (dataCursor.moveToFirst()) 

您将数据光标移动到指向每个呼叫中​​不需要的第一个元素,这将撤消功能顶部的以下行:

dataCursor.moveToPosition(position); 

如果您删除if语句,它应该正常工作

+0

Hi @pooya仍然有与您的解决方案相同的问题 –

+0

@ D.O。这很难从这里调试,但是在你的代码中也有一些语义问题,例如(phones.moveToNext())需要在这之前有phones.moveToFirst()。请参阅是否可以先纠正这些问题以获得更可靠的输出 – Pooya

+0

这是我在尝试在我的代码中读取所有电话号码的实现。也许这可以帮助你给我一些解决方案。是@anivaler的答案http://stackoverflow.com/questions/2356084/read-all-contacts-phone-numbers-in-android –

相关问题