RecyclerView过滤更新了回收站视图错误

时间:2017-02-01 13:33:24

标签: android list android-recyclerview notifydatasetchanged

我有一个回收站视图,其中显示手机通讯录。您可以通过复选框选择或取消选择列表中的联系人。回收站视图显示在活动上。导航到该活动,我将转移所有在显示列表之前和之后选择的联系人,我将手机联系人与所选联系人进行比较,以便在列表中默认选择它们。所以我有两个传递给适配器的列表: 电话联系人列表 选择的联系人列表 。我让用户按显示名称过滤联系人列表,因此我在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;
}

}

0 个答案:

没有答案