我想获取联系人列表(名称&&照片)并显示 它在 RecyclerView 。
我使用了几种方法,但它们有一种方法 常见问题:联系人的照片及其名称 - 不匹配。
即照片uri错误并且每个联系人都感到困惑。
我尝试使用这些方法:
Standart方式
通讯录库
简易内容提供商库
这是最重要的:
模型类:
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
答案 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));
}
}
一切都变好了。