联系人的照片是错误的

时间:2016-09-30 11:27:59

标签: android

我想获取联系人列表(名称&&照片)并显示 它在 RecyclerView

我使用了几种方法,但它们有一种方法 常见问题:联系人的照片及其名称 - 不匹配

即照片uri错误并且每个联系人都感到困惑。

enter image description here

我尝试使用这些方法:

这是最重要的:

模型类

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

我所测试的所有设备都存在问题:

  • Xiaomi Redmi Note 2 - 5.1.0

  • 三星Galaxy S6 - 6.0.1

  • Nexus 5x - 7.0.0

1 个答案:

答案 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));
    }
  }
一切都变好了。