我有一个回收站视图,其中显示手机通讯录。您可以通过复选框选择或取消选择列表中的联系人。回收站视图显示在活动上。导航到该活动,我将转移所有在显示列表之前和之后选择的联系人,我将手机联系人与所选联系人进行比较,以便在列表中默认选择它们。所以我有两个传递给适配器的列表: 电话联系人列表 和 选择的联系人列表 。我让用户按显示名称过滤联系人列表,因此我在EditText上绑定了一个TextWatcher事件,该事件在文本更改后重新加载了recyclerview。但问题是当用户开始过滤时,所选择的联系人列表正在从无处填充,我在所选联系人列表中获得了所有电话联系人....非常奇怪......
这是适配器:
public class ContactsChooserAdapter extends RecyclerView.Adapter<ContactChooserViewHolder> {
private ArrayList<Contact> mContacts;
private ArrayList<Contact> mSelectedContacts;
private OnContactSelectionListener mContactListener;
public ContactsChooserAdapter(ArrayList<Contact> contacts, ArrayList<Contact> selectedContacts)
{
mContacts = contacts;
mSelectedContacts = selectedContacts;
}
public void setOnContactSelectionListener(OnContactSelectionListener listener)
{
mContactListener = listener;
}
@Override
public ContactChooserViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.contacts_chooser_list_item, parent, false);
ContactChooserViewHolder holder = new ContactChooserViewHolder(v);
return holder;
}
@Override
public void onBindViewHolder(ContactChooserViewHolder holder, int position) {
Contact contact = getContacts().get(position);
if(isAlreadySelected(contact)){
holder.mChoosed.setChecked(true);
}else{
holder.mChoosed.setChecked(false);
}
holder.mContactDisplayName.setText(contact.getDisplayName());
holder.mContactPhoneNumber.setText(contact.getPhoneNumbers().get(0));
if(mContactListener != null) {
holder.bind(contact, mContactListener);
}
}
@Override
public int getItemCount() {
return getContacts().size();
}
/**
* Method which allows to check whenever a contact is already selected in a list or not.
* @param contact
* @return
*/
private boolean isAlreadySelected(Contact contact){
boolean alreadySelected = false;
if(getAlreadySelectedContacts() != null){
System.out.println("ALready selected contact list: "+ getAlreadySelectedContacts().size());
for(Contact c : getAlreadySelectedContacts()){
if(c.getId() == contact.getId()){
alreadySelected = true;
break;
}
}
}
return alreadySelected;
}
public ArrayList<Contact> getContacts() {
return mContacts;
}
public void setContacts(ArrayList<Contact> mContacts) {
this.mContacts = mContacts;
}
public ArrayList<Contact> getAlreadySelectedContacts() {
return mSelectedContacts;
}
public void setAlreadySelectedContacts(ArrayList<Contact> selectedContacts) {
this.mSelectedContacts = selectedContacts;
}
}
以下是活动:
public class ContactsActivity extends AppCompatActivity {
private ArrayList<Contact> mSelectedContacts;
private ArrayList<Contact> mPhoneContacts;
private RecyclerView mContactsList;
private BatifyTextViewBold mContactsNbLabel;
private BatifyEditText mSearchEditText;
private ContactsChooserAdapter mContactsChooserAdapter;
private LinearLayoutManager mLinearLayoutManager;
private RelativeLayout mCancelBtn;
private RelativeLayout mFinishBtn;
private ImageView mSearchIcon;
private RelativeLayout mListHeader;
private RelativeLayout mSearchLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contacts);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = this.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.setStatusBarColor(ContextCompat.getColor(this, R.color.batifyGreen));
}
Bundle bundle = getIntent().getExtras();
ArrayList<Contact> transmittedContacts = bundle.getParcelableArrayList(GlobalVariables.CONTACTS_SELECTED_CONTACTS_LABEL);
mSelectedContacts = new ArrayList<>();
if(transmittedContacts != null) {
mSelectedContacts.addAll(transmittedContacts);
}
mContactsList = (RecyclerView)findViewById(R.id.contactsList);
mContactsNbLabel = (BatifyTextViewBold)findViewById(R.id.contactNbSelectedTv);
if(getSelectedContacts() == null){
mContactsNbLabel.setText("0 contact ");
}else{
mContactsNbLabel.setText(getSelectedContacts().size() + (getSelectedContacts().size() > 1 ? " contacts " : " contact "));
}
mFinishBtn = (RelativeLayout)findViewById(R.id.finishContactsBtn);
mFinishBtn.setOnClickListener(finishChoosingContactsListener);
mCancelBtn = (RelativeLayout)findViewById(R.id.cancelContactsBtn);
mCancelBtn.setOnClickListener(cancelChoosingContactsListener);
mSearchIcon = (ImageView)findViewById(R.id.searchBtn);
mSearchIcon.setOnClickListener(searchListener);
mListHeader = (RelativeLayout)findViewById(R.id.listHeader);
mListHeader.setVisibility(View.VISIBLE);
mSearchLayout = (RelativeLayout)findViewById(R.id.searchLayout);
mSearchLayout.setVisibility(View.GONE);
mSearchEditText = (BatifyEditText)findViewById(R.id.searchContactsEditText);
mSearchEditText.addTextChangedListener(searchViewWatcher);
requestPermissionForContactsAndProcess();
}
/**
* Method that requests the permission to access contacts.
*/
public void requestPermissionForContactsAndProcess() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED)
{
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_CONTACTS)) {
Tools.showPopUpCallBack(this, "Information", getString(R.string.contactRationalMessage), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON_POSITIVE)
{
requestPermissionForContactsAndProcess();
}
}
});
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, GlobalVariables.CONTACTS_PERMISSIONS);
}
}else{
getAllContactsAndDisplay();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case GlobalVariables.CONTACTS_PERMISSIONS: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getAllContactsAndDisplay();
}
return;
}
}
}
/**
* Method which allows to display a contacts list
*/
public void displayContactList(){
mContactsChooserAdapter = new ContactsChooserAdapter(getPhoneContacts(), getSelectedContacts());
mContactsChooserAdapter.setOnContactSelectionListener(contactSelectionListener);
mLinearLayoutManager = new LinearLayoutManager(this);
mContactsList.setLayoutManager(mLinearLayoutManager);
mContactsList.setAdapter(mContactsChooserAdapter);
}
/**
* Method that will retrieve all contacts.
*/
private void getAllContactsAndDisplay()
{
mPhoneContacts = new ArrayList<>();
Contact contact;
ContentResolver contentResolver = getContentResolver();
Cursor cursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
if (cursor.getCount() > 0) {
while (cursor.moveToNext()) {
int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)));
if (hasPhoneNumber > 0) {
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
String displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
contact = new Contact();
contact.setId(Integer.parseInt(id));
contact.setDisplayName(displayName);
Cursor phoneCursor = contentResolver.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
new String[]{id},
null);
if (phoneCursor.moveToNext()) {
String phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
contact.getPhoneNumbers().add(phoneNumber);
}
phoneCursor.close();
getPhoneContacts().add(contact);
}
}
}
displayContactList();
}
/**
* Method which allow to finish and close the activity. It returns a result.
*/
public void finishedChoosingContacts()
{
Intent intent= new Intent();
intent.putParcelableArrayListExtra(GlobalVariables.CONTACTS_SELECTED_CONTACTS_LABEL, getSelectedContacts());
setResult(Activity.RESULT_OK, intent);
finish();
}
/**
* Listener which allows to select and deselect a contact in a list.
*/
private OnContactSelectionListener contactSelectionListener = new OnContactSelectionListener() {
@Override
public void onContactSelected(Contact contact) {
if(getSelectedContacts() == null){
setSelectedContacts(new ArrayList<Contact>());
}
getSelectedContacts().add(contact);
mContactsNbLabel.setText(getSelectedContacts().size() + (getSelectedContacts().size() > 1 ? " contacts " : " contact "));
}
@Override
public void onContactDeSelected(Contact contact) {
int indexToDelete = -1;
for(Contact c : getSelectedContacts()){
if(c.getId() == contact.getId()){
indexToDelete = getSelectedContacts().indexOf(c);
break;
}
}
if(indexToDelete > -1) {
getSelectedContacts().remove(indexToDelete);
mContactsNbLabel.setText(getSelectedContacts().size() + (getSelectedContacts().size() > 1 ? " contacts " : " contact "));
}
}
};
/**
* Listener which is fired when the search edit text value is changing.
*/
private TextWatcher searchViewWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
filterListAndUpdate(s.toString());
}
};
/**
* method used to filter and update the list
* @param searchedValue
*/
private void filterListAndUpdate(String searchedValue)
{
ArrayList<Contact> associatedSearch = new ArrayList<>();
if(!"".equals(searchedValue) && searchedValue != null) {
for (Contact c : getPhoneContacts()) {
if (c.getDisplayName().toUpperCase().startsWith(searchedValue.toUpperCase())) {
associatedSearch.add(c);
}
}
((ContactsChooserAdapter)mContactsList.getAdapter()).setContacts(associatedSearch);
}else{
((ContactsChooserAdapter)mContactsList.getAdapter()).setContacts(getPhoneContacts());
}
mContactsList.getAdapter().notifyDataSetChanged();
}
/**
* Listener that allows to fire the search listener.
*/
private View.OnClickListener searchListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
mListHeader.setVisibility(View.GONE);
mSearchLayout.setVisibility(View.VISIBLE);
}
};
/**
* Listener which is fired when the user cancels the contacts selection.
*/
private View.OnClickListener cancelChoosingContactsListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
};
/**
* Listener which id fired when the user finishes selecting contacts.
*/
private View.OnClickListener finishChoosingContactsListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
finishedChoosingContacts();
}
};
public ArrayList<Contact> getSelectedContacts() {
return mSelectedContacts;
}
public void setSelectedContacts(ArrayList<Contact> mSelectedContacts) {
this.mSelectedContacts = mSelectedContacts;
}
public ArrayList<Contact> getPhoneContacts() {
return mPhoneContacts;
}
}