object is not getting removed from list onCheckedC

2019-09-14 21:45发布

问题:

I have a list of contacts. I have a check box to select the contacts. These selected contacts I want to add in another list called invitation array list. I have created a method to add all contacts in invitation list if check box is selected called as toogleContactsSelection. This I am using in an activity.

I have created another method to add contacts in invitation arraylist if check box is selected.

Now I want to remove the object from an invitation array list if check box is unchecked i.e onCheckChangeListener of check box.

But object is not getting removed from invitationArrayList.

Adapter:

     public class InviteAdapter extends RecyclerView.Adapter<InviteAdapter.MyViewHolder> {

        private ArrayList<Contact> contactArrayList;
        private Context mContext;
        public ArrayList<Invitation>  invitationArrayList = new ArrayList<>();

        public class MyViewHolder extends RecyclerView.ViewHolder {
            public TextView name;
            private CheckBox checkBox;

            public MyViewHolder(View view) {
                super(view);
                name = (TextView) view.findViewById(R.id.textContactName);
                checkBox = (CheckBox) view.findViewById(R.id.checkBox);

            }
        }

        public InviteAdapter(Context context, ArrayList<Contact> contactArrayList) {
            this.contactArrayList = contactArrayList;
            this.mContext = context;

        }

        @Override
        public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View itemView = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.invite_contact_item, parent, false);

            return new MyViewHolder(itemView);
        }

        @Override
        public void onBindViewHolder(MyViewHolder holder, final int position) {
            final Contact contact = contactArrayList.get(position);
            holder.name.setText(contact.getmFullName());

            holder.checkBox.setChecked(contact.getSelected());

            holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton compoundButton, boolean b) {

                    if(b)
                    {
                        invite(contact);

                        Log.e("inviteList",String.valueOf(invitationArrayList.size()));
                    }
                    else {
                        invitationArrayList.remove(contact);

                        Log.e("inviteList",String.valueOf(invitationArrayList.size()));
                    }
                }
            });
        }

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

        }

        public void toggleContactsSelection( boolean isSelected ) {
            for( Contact contact : contactArrayList ) {
                contact.setSelected(isSelected);

                    invite(contact);

            }
            notifyDataSetChanged(); // OR you can use notifyItemRangeChanged - which ever suits your needs
        }

        public void invite(Contact contact)
        {

            SharedPreferences sharedpreferences = mContext.getSharedPreferences("UserId", Context.MODE_PRIVATE);

            String mUserId = sharedpreferences.getString("userId","");

            DateFormat df = new SimpleDateFormat("EEE, d MMM yyyy, HH:mm", Locale.ENGLISH);
            String date = df.format(Calendar.getInstance().getTime());

            Invitation invitation = new Invitation();

            invitation.setSender_id(mUserId);
            invitation.setDate(date);
            invitation.setInvitee_no(contact.getmMobileNo());
            invitation.setStatus("0");
            invitation.setUser_name(contact.getmUserName());

            invitationArrayList.add(invitation);

        }

        public void removeInvite(int position)
        {
            invitationArrayList.remove(position);
        }

        public ArrayList<Invitation> getArrayList(){
            return invitationArrayList;
        }

    }


What is going wrong?

EDIT:

This is an adpater :


   public class InviteAdapter extends RecyclerView.Adapter<InviteAdapter.MyViewHolder> {

    private ArrayList<Contact> contactArrayList;
    private Context mContext;
    public ArrayList<Invitation>  invitationArrayList = new ArrayList<>();

    public class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView name;
        private CheckBox checkBox;

        public MyViewHolder(View view) {
            super(view);
            name = (TextView) view.findViewById(R.id.textContactName);
            checkBox = (CheckBox) view.findViewById(R.id.checkBox);

        }
    }

    public InviteAdapter(Context context, ArrayList<Contact> contactArrayList) {
        this.contactArrayList = contactArrayList;
        this.mContext = context;

    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.invite_contact_item, parent, false);

        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(final MyViewHolder holder, final int position) {
        final Contact contact = contactArrayList.get(holder.getAdapterPosition());
        holder.name.setText(contact.getmFullName());

        holder.checkBox.setChecked(contact.getSelected());

        holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {

                if(b)
                {
                    invite(contact);

                    Log.e("inviteList",String.valueOf(invitationArrayList.size()));
                }
                else {

                    contactArrayList.get(position).setSelected(false);
                 //   holder.checkBox.setChecked(false);
                  // updateInvites();
                    Log.e("inviteList",String.valueOf(invitationArrayList.size()));
                }
            }
        });
    }

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

    }
    public void setChecked()
    {
        for( Contact contact : contactArrayList ) {


        }
    }


    public void toggleContactsSelection( boolean isSelected ) {
        for( Contact contact : contactArrayList ) {
            contact.setSelected(isSelected);

                invite(contact);

        }
        notifyDataSetChanged(); // OR you can use notifyItemRangeChanged - which ever suits your needs
    }

    public void invite(Contact contact)
    {

        Invitation invitation = new Invitation();

            SharedPreferences sharedpreferences = mContext.getSharedPreferences("UserId", Context.MODE_PRIVATE);

            String mUserId = sharedpreferences.getString("userId", "");

            DateFormat df = new SimpleDateFormat("EEE, d MMM yyyy, HH:mm", Locale.ENGLISH);
            String date = df.format(Calendar.getInstance().getTime());

            invitation.setSender_id(mUserId);
            invitation.setDate(date);
            invitation.setInvitee_no(contact.getmMobileNo());
            invitation.setStatus("0");
            invitation.setUser_name(contact.getmUserName());
            invitation.setContact_id(contact.getContactId());

            invitationArrayList.add(invitation);

    }
    public ArrayList<Invitation> getArrayList(){
        return invitationArrayList;
    }

    public void updateInvites(){
        invitationArrayList.clear();
        for(Contact contact : contactArrayList){
            if(contact.getSelected()){

                invite(contact);
            }
        }
    }
}

And here is an activity's code:

  sendInvites.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            mAdapter.updateInvites(); // updating list on sendInvites, 

            invitationArrayList = mAdapter.getArrayList();

            Log.e("inviteList",String.valueOf(invitationArrayList.size()));

            Gson gson = new Gson();
            String toServer = gson.toJson(
                    Collections.singletonMap("invitations", invitationArrayList)
            );

            new SendMultipleInvitesAsyncTask(InviteContactsActivity.this,InviteContactsActivity.this).execute(toServer);

            finish();
            Intent i = new Intent(InviteContactsActivity.this,InviteContactsActivity.class);
            i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
            startActivity(i);
        }
    });

Now I am updating list onSendInvites, but when I check or uncheck the api it dose not behave as expected.

回答1:

OK, so there are few silly mistakes I say,

a. Replace

final Contact contact = contactArrayList.get(position);

with

final Contact contact = contactArrayList.get(holder.getAdapterPosition());

b. You are adding Object of Class Invitation

Invitation invitation = new Invitation();
    invitation.setSender_id(mUserId);
    invitation.setDate(date);
    invitation.setInvitee_no(contact.getmMobileNo());
    invitation.setStatus("0");
    invitation.setUser_name(contact.getmUserName());

    invitationArrayList.add(invitation);

c. You are trying to remove object of Class Contacts

else {
                    invitationArrayList.remove(contact);

                    Log.e("inviteList",String.valueOf(invitationArrayList.size()));
                }

Solution

in onBindViewHolder

   holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
            contactArrayList.get(holder.getAdapterPosition()).setSelected(b);
            Log.e("inviteList",String.valueOf(invitationArrayList.size()));
            }
        });

then make a method like

private void updateInvites(){
    invitationArrayList.clear();
    for(Contacts contacts : contactsArrayList){
        if(contacts.isSelected()){
             invite(contact);
        }
    }
}

here contact.setSeletected(boolean status) and contact.isSelected() are setters and getters respectively

EDIT: Here is the link to my blog on RecyclerView which explains most of the concepts of Simple RecyclerView.



回答2:

instead of using object to remove use index to remove item:

   invitationArrayList.remove(position);

it will work.

You are getting index out of bound because there may be possibility user is removing the item before adding it. may be particular element in not present in your invitationArrayList. So for this try this code:

if (invitationArrayList!=null && invitationArrayList.size() > 0 && invitationArrayList.size() > position +1){
 invitationArrayList.remove(position);
}