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

#java #android #arraylist #checkbox #oncheckedchanged

#java #Android #arraylist #флажок #oncheckedchanged

Вопрос:

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

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

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

Но объект не удаляется из invitationArrayList.

Адаптер:

      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, он ведет себя не так, как ожидалось.

Комментарии:

1. вы можете установить флажок (position) для флажка и получить его положение и удалить элемент в той же позиции

Ответ №1:

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

a. Заменить

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

c. Вы пытаетесь удалить объект класса 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, в котором объясняется большинство концепций простого RecyclerView.

Комментарии:

1. где использовать updateInvites()? Я не понимаю, пожалуйста, можете ли вы объяснить подробно? @Mohammed Atif

2. приглашения на обновление будут последним методом, который вы вызовете. непосредственно перед использованием invitationArrayList

3. Предположим, вы используете invitationArrayList() для выполнения вызова API. вызовите этот метод updateInvites() непосредственно перед выполнением вызова. это обновит ваш список приглашений выбранными объектами, а затем вы сможете использовать этот обновленный список для выполнения вызова.

4. не могли бы вы проверить отредактированный вопрос? @ Mohammed Atif

5. НЕТ, это не то, как вы должны реализовать updateInvites() . Не помещайте этот вызов метода в место, которое динамически меняется. Если у вас есть что-то похожее на кнопку done, поместите ее туда. И я добавил ссылку на свой блог в RecyclerView в ответ, вы также можете просмотреть это, чтобы узнать, как обновлять списки при ответе пользователя.

Ответ №2:

вместо использования object для удаления используйте index для удаления элемента:

    invitationArrayList.remove(position);
  

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

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

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

Комментарии:

1. Я попытался использовать это, но это дало мне исключение indexOutOfBound. @Anjali

2. нет, он не работает, он не переходит в условие if. @Anjali

3. да, очевидно, что он не войдет в ваш список, если он не содержит этого объекта