2016-09-30 45 views
4

我要取的接觸(名稱& &照片)列表,顯示 它RecyclerView聯繫人的照片的URI是錯誤的

我使用了幾種方法,但他們有一個 常見問題:聯繫人的照片和它的名字 - 不匹配

I.e照片uri對於每個聯繫人都是錯誤的和困惑的。

enter image description here

我tryed使用這些方法:

這是最重要的:

Model類

public class ContactModel { 

    private String name; 
    private String photoUri; 

    public String getName() { 
    return name; 
    } 

    public void setName(String name) { 
    this.name = name; 
    } 

    public String getPhotoUri() { 
    return photoUri; 
    } 

    public void setPhotoUri(String photoUri) { 
    this.photoUri = photoUri; 
    } 
} 

XML項目

<?xml version="1.0" encoding="utf-8"?> 
<layout xmlns:android="http://schemas.android.com/apk/res/android" 
     xmlns:app="http://schemas.android.com/apk/res-auto" 
    > 

    <data> 

     <variable 
      name="contact" 
      type="xyz.letscoder.testcontacts.model.ContactModel" /> 
    </data> 

    <LinearLayout 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:orientation="horizontal"> 

     <ImageView 
      android:id="@+id/item_contact_icon" 
      android:layout_width="48dp" 
      android:layout_height="48dp" 
      android:layout_marginBottom="16dp" 
      app:icon="@{contact.photoUri}" 
      android:layout_marginTop="16dp" /> 

     <TextView 
      android:id="@+id/item_contact_name" 
      android:layout_width="wrap_content" 
      android:layout_height="match_parent" 
      android:layout_gravity="center" 
      android:layout_marginLeft="16dp" 
      android:layout_marginStart="16dp" 
      android:gravity="center" 
      android:text="@{contact.name}" /> 

    </LinearLayout> 
</layout> 

適配器代碼

public class ContactItemAdapter 
    extends RecyclerView.Adapter<ContactItemAdapter.ContactItemViewHolder> { 

    private List<ContactModel> contacts; 

    public ContactItemAdapter(List<ContactModel> contacts) { 
    this.contacts = contacts; 
    } 

    @Override 
    public ContactItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    LayoutInflater inflater = LayoutInflater.from(parent.getContext()); 
    ItemContactBinding binding = ItemContactBinding.inflate(inflater, parent, false); 
    return new ContactItemViewHolder(binding.getRoot()); 
    } 

    @Override 
    public void onBindViewHolder(ContactItemViewHolder holder, int position) { 
    ContactModel model = contacts.get(position); 
    holder.binding.setContact(model); 
    } 

    @Override 
    public int getItemCount() { 
    return contacts.size(); 
    } 

    /** 
    * ViewHolder for contact item 
    */ 
    class ContactItemViewHolder extends RecyclerView.ViewHolder { 

    private ItemContactBinding binding; 

    ContactItemViewHolder(View itemView) { 
     super(itemView); 
     binding = DataBindingUtil.bind(itemView); 
    } 

    } 

    /** 
    * Bind icon 
    */ 
    @BindingAdapter("bind:icon") 
    public static void loadIcon(ImageView imageView, String v) { 
    if(v != null) 
    imageView.setImageURI(Uri.parse(v)); 
    } 

} 

活動代碼

public class MainActivity extends AppCompatActivity { 

    private RecyclerView recyclerView; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    setupRecyclerView(); 
    } 

    private void setupRecyclerView() { 
    recyclerView = (RecyclerView) findViewById(R.id.recycler_view); 
    LinearLayoutManager layoutManager = new LinearLayoutManager(this); 
    recyclerView.setLayoutManager(layoutManager); 
    showContacts(); 
    } 

    private void showContacts() { 
    if (PermissionUtils.isReadContactsPermissionGranted(this)) { 
     setupAdapter(); 
    } else { 
     PermissionUtils.requestReadContactsPermission(this); 
    } 
    } 

    private void setupAdapter() { 
    ContactItemAdapter adapter = new ContactItemAdapter(fetchContacts()); 
    recyclerView.setAdapter(adapter); 
    } 

    // Commented code is the methods of get contacts 
    private List<ContactModel> fetchContacts() { 
    /*return ContactFetchUtils.getContactsWithNativeMethod(this);*/ 
    /*return ContactFetchUtils.getContactsWithEasyProvidersLibrary(this);*/ 
    return ContactFetchUtils.getContactsWithContactsLibrary(); 
    } 

    @Override 
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, 
     @NonNull int[] grantResults) { 
    super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
    if (PermissionUtils.isReadContactsPermissionGranted(requestCode, grantResults)) { 
     setupAdapter(); 
    } 

    } 
} 

提取通訊錄utils的代碼

public final class ContactFetchUtils { 

    private ContactFetchUtils() { /* empty private constructor */ } 

    // standart android method 
    public static List<ContactModel> getContactsWithNativeMethod(Context context) { 
    List<ContactModel> contacts = new ArrayList<>(); 
    Cursor phones = context.getContentResolver() 
     .query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, 
      null, null, null, null); 
    while (phones.moveToNext()) { 

     String name = phones.getString(
      phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); 
     String photoUri = phones.getString(
      phones.getColumnIndex(ContactsContract.CommonDataKinds.Photo.PHOTO_THUMBNAIL_URI)); 

     ContactModel contact = new ContactModel(); 
     contact.setPhotoUri(photoUri); 
     contact.setName(name); 
     contacts.add(contact); 

    } 
    phones.close(); 
    return contacts; 
    } 

    // me.everything.providers 
    public static List<ContactModel> getContactsWithEasyProvidersLibrary(Context context) { 
    ContactsProvider provider = new ContactsProvider(context); 
    List<ContactModel> models = new ArrayList<>(); 
    List<me.everything.providers.android.contacts.Contact> contacts = provider.getContacts() 
     .getList(); 
    for (me.everything.providers.android.contacts.Contact contact : contacts) { 
     ContactModel model = new ContactModel(); 
     model.setName(contact.displayName); 
     model.setPhotoUri(contact.uriPhoto); 
     models.add(model); 
    } 
    return models; 
    } 

    // com.github.tamir7.contacts 
    public static List<ContactModel> getContactsWithContactsLibrary() { 
    List<Contact> contacts = Contacts.getQuery().find(); 
    List<ContactModel> models = new ArrayList<>(); 
    for (Contact contact : contacts) { 
     ContactModel model = new ContactModel(); 
     model.setName(contact.getDisplayName()); 
     model.setPhotoUri(contact.getPhotoUri()); 
     models.add(model); 
    } 
    return models; 
    } 
} 

上的所有設備中存在的問題,我測試過:

  • 小蜜紅米手機注2 - 5.1.0

  • 三星Galaxy S6 - 6.0.1

  • 的Nexus 5X - 7.0.0

回答

0

一些調試運行後,我有一個回答。 看來問題是事實,RecyclerView被重用舊視圖來顯示信息,而且由於這些代碼它使用另一張照片:

@BindingAdapter("bind:icon") 
    public static void loadIcon(ImageView imageView, String v) { 
    if(v != null) 
    imageView.setImageURI(Uri.parse(v)); 
    } 

當我把它改爲:

@BindingAdapter("bind:icon") 
    public static void loadIcon(ImageView imageView, String v) { 
    if (v == null || v.equals("")) { 
     imageView.setImageURI(null); 
    } else { 
     imageView.setImageURI(Uri.parse(v)); 
    } 
    } 

所有成爲確定。