объект не удаляется из списка прослушивателя onCheckedChange флажка

У меня есть список контактов. У меня есть флажок для выбора контактов. Эти выбранные контакты я хочу добавить в другой список, называемый списком массивов приглашений. Я создал метод для добавления всех контактов в список приглашений, если установлен флажок, который называется toogleContactsSelection. Это я использую в действии.

Я создал еще один метод для добавления контактов в массив приглашений, если установлен флажок.

Теперь я хочу удалить объект из списка массивов приглашений, если флажок не установлен, т.е. onCheckChangeListener флажка.

Но объект не удаляется из списка приглашенийArrayList.

Адаптер:

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

И вот код активности:

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

Теперь я обновляю список onSendInvites, но когда я проверяю или снимаю флажок с API, он ведет себя не так, как ожидалось.


person Sid    schedule 04.10.2016    source источник
comment
вы можете установитьTag(position) для флажка и получить его положение и удалить элемент в той же позиции   -  person Ganesh Gudghe    schedule 04.10.2016


Ответы (2)


Итак, я говорю, что есть несколько глупых ошибок,

а. Заменять

final Contact contact = contactArrayList.get(position);

с

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

б. Вы добавляете объект класса 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);

в. Вы пытаетесь удалить объект класса Contacts

else {
                    invitationArrayList.remove(contact);

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

Решение

в 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()));
            }
        });

затем сделайте метод вроде

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

здесь contact.setSeletected(boolean status) и contact.isSelected() - сеттеры и геттеры соответственно

РЕДАКТИРОВАТЬ: Вот ссылка на мой блог на RecyclerView, в котором объясняется большинство концепций Simple RecyclerView.

person Mohammed Atif    schedule 04.10.2016
comment
где использовать updateInvites()? Я не понимаю, пожалуйста, можете ли вы объяснить подробно? @Мохаммед Атиф - person Sid; 04.10.2016
comment
приглашения на обновление будут последним методом, который вы вызовете. непосредственно перед использованием InvitationArrayList - person Mohammed Atif; 05.10.2016
comment
Предположим, вы используете invitationArrayList() для вызова API. вызовите этот метод updateInvites() непосредственно перед выполнением вызова. это обновит ваш список приглашений выбранными объектами, а затем вы сможете использовать этот обновленный список для совершения вызова. - person Mohammed Atif; 05.10.2016
comment
не могли бы вы проверить отредактированный вопрос? @ Мохаммед Атиф - person Sid; 05.10.2016
comment
НЕТ, это не то, как вы должны реализовать updateInvites(). Не размещайте вызов этого метода в месте, которое динамически изменяется. Если у вас есть что-то похожее на кнопку «Готово», поместите ее туда. И я добавил ссылку на свой блог на RecyclerView в ответ, вы также можете просмотреть это, чтобы увидеть, как обновлять списки по ответу пользователя. - person Mohammed Atif; 06.10.2016
comment
Если я использую его и для кнопки отправки, то, поскольку список массивов становится ясным в методе updateInvite, тогда список становится равным 0, хотя флажки отмечены. @Мохаммед Атиф - person Sid; 06.10.2016
comment
список приглашений очищается, затем записывается цикл for, чтобы в списке присутствовали новые записи. Не могли бы вы полностью обновить свой новый код под меткой EDIT. Я думаю, вы делаете что-то не так - person Mohammed Atif; 06.10.2016
comment
Я обновил решение, один раз исправил код onItemCheckedListener - person Mohammed Atif; 06.10.2016
comment
Давайте продолжим обсуждение в чате. - person Mohammed Atif; 06.10.2016

вместо использования объекта для удаления используйте индекс для удаления элемента:

   invitationArrayList.remove(position);

это будет работать.

Вы получаете индекс за пределы привязки, потому что может быть вероятность того, что пользователь удалит элемент перед его добавлением. может быть определенный элемент, отсутствующий в вашем inventoryArrayList. Итак, для этого попробуйте этот код:

if (invitationArrayList!=null && invitationArrayList.size() > 0 && invitationArrayList.size() > position +1){
 invitationArrayList.remove(position);
}
person Anjali    schedule 04.10.2016
comment
Я пытался использовать это, но это дало мне исключение indexOutOfBound. @Анжали - person Sid; 04.10.2016
comment
нет, он не работает, он не переходит в состояние if. @Анжали - person Sid; 04.10.2016
comment
да, очевидно, он не войдет в ваш список, если он не содержит этого объекта - person Anjali; 05.10.2016