Android RecyclerView добавление и удаление элементов

У меня есть RecyclerView с текстовым полем TextView и крест-кнопкой ImageView. У меня есть кнопка за пределами recyclerview, которая делает крест-кнопку ImageView видимой / удаленной.

Я ищу, чтобы удалить элемент из recylerview, когда нажата кнопка CrossView ImageView.

Мой адаптер:

public class MyAdapter extends RecyclerView.Adapter implements View.OnClickListener, View.OnLongClickListener { private ArrayList mDataset; private static Context sContext; public MyAdapter(Context context, ArrayList myDataset) { mDataset = myDataset; sContext = context; } @Override public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_text_view, parent, false); ViewHolder holder = new ViewHolder(v); holder.mNameTextView.setOnClickListener(MyAdapter.this); holder.mNameTextView.setOnLongClickListener(MyAdapter.this); holder.mNameTextView.setTag(holder); return holder; } @Override public void onBindViewHolder(ViewHolder holder, int position) { holder.mNameTextView.setText(mDataset.get(position)); } @Override public int getItemCount() { return mDataset.size(); } @Override public void onClick(View view) { ViewHolder holder = (ViewHolder) view.getTag(); if (view.getId() == holder.mNameTextView.getId()) { Toast.makeText(sContext, holder.mNameTextView.getText(), Toast.LENGTH_SHORT).show(); } } @Override public boolean onLongClick(View view) { ViewHolder holder = (ViewHolder) view.getTag(); if (view.getId() == holder.mNameTextView.getId()) { mDataset.remove(holder.getPosition()); notifyDataSetChanged(); Toast.makeText(sContext, "Item " + holder.mNameTextView.getText() + " has been removed from list", Toast.LENGTH_SHORT).show(); } return false; } public static class ViewHolder extends RecyclerView.ViewHolder { public TextView mNumberRowTextView; public TextView mNameTextView; public ViewHolder(View v) { super(v); mNameTextView = (TextView) v.findViewById(R.id.nameTextView); } } } 

Мой макет:

      

Как я могу получить что-то вроде onClick, работающего для моего crossButton ImageView? Есть ли способ лучше? Возможно, изменение всего элемента onclick на удаление элемента? В recyclerview показан список мест, которые необходимо отредактировать. Любые технические рекомендации или комментарии / предложения по наилучшей реализации будут чрезвычайно оценены.

12 Solutions collect form web for “Android RecyclerView добавление и удаление элементов”

Я сделал что-то подобное. В вашем MyAdapter :

 public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{ public CardView mCardView; public TextView mTextViewTitle; public TextView mTextViewContent; public ImageView mImageViewContentPic; //...... public ImageView imgViewRemoveIcon; public ViewHolder(View v) { super(v); mCardView = (CardView) v.findViewById(R.id.card_view); mTextViewTitle = (TextView) v.findViewById(R.id.item_title); mTextViewContent = (TextView) v.findViewById(R.id.item_content); mImageViewContentPic = (ImageView) v.findViewById(R.id.item_content_pic); //...... imgViewRemoveIcon = (ImageView) v.findViewById(R.id.remove_icon); mTextViewContent.setOnClickListener(this); imgViewRemoveIcon.setOnClickListener(this); v.setOnClickListener(this); mTextViewContent.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View view) { if (mItemClickListener != null) { mItemClickListener.onItemClick(view, getPosition()); } return false; } }); } @Override public void onClick(View v) { //Log.d("View: ", v.toString()); //Toast.makeText(v.getContext(), mTextViewTitle.getText() + " position = " + getPosition(), Toast.LENGTH_SHORT).show(); if(v.equals(imgViewRemoveIcon)){ removeAt(getPosition()); }else if (mItemClickListener != null) { mItemClickListener.onItemClick(v, getPosition()); } } } public void setOnItemClickListener(final OnItemClickListener mItemClickListener) { this.mItemClickListener = mItemClickListener; } public void removeAt(int position) { mDataset.remove(position); notifyItemRemoved(position); notifyItemRangeChanged(position, mDataSet.size()); } 

Надеюсь это поможет.

Редактировать:

getPosition() теперь getAdapterPosition() использования вместо getAdapterPosition() .

прежде всего, элемент должен быть удален из списка!

  mDataSet.remove(getAdapterPosition()); 

тогда:

  notifyItemRemoved(getAdapterPosition()); notifyItemRangeChanged(getAdapterPosition(),mDataSet.size()); 

если по-прежнему элемент не удален, используйте этот волшебный метод 🙂

 private void deleteItem(int position) { mDataSet.remove(position); notifyItemRemoved(position); notifyItemRangeChanged(position, mDataSet.size()); holder.itemView.setVisibility(View.GONE); } 

Я попробовал все вышеперечисленные ответы, но вставка или удаление элементов для recyclerview вызывает проблему с положением в наборе данных. Закончено с помощью delete(getAdapterPosition()); внутри viewHolder, который отлично справился с поиском позиции предметов.

На самом деле с ранее упомянутым кодом (это вы можете найти здесь ниже) все дочерние элементы RecyclerView анимируются, когда один элемент удаляется, и это не отзывчивое решение вообще, также потому, что оно имеет некоторые потенциальные скрытые проблемы

 public void remove(int position) { dataset.remove(position); notifyItemRemoved(position); notifyItemRangeChanged(position, mDataSet.size()); } 

Вместо этого следующий fragment будет воспроизводить анимацию только у дочернего объекта, который удаляется, и с моей стороны он прекратил бросать IndexOutOfBoundException s, помеченный отладчиком как «несогласованность данных»,

 void remove(int position) { dataset.removeAt(position); notifyItemChanged(position); notifyItemRangeRemoved(position, 1); } 

Если мы перейдем к classу RecyclerView мы найдем кусок javadoc, у которого есть объяснение, действительно как второй параметр, мы должны передать количество элементов, которые удалены из набора данных, а не общее количество элементов

  /** * Notify any registered observers that the itemCount items previously * located at positionStart have been removed from the data set. The items * previously located at and after positionStart + itemCount may now be found * at oldPosition - itemCount. * * 

This is a structural change event. Representations of other existing items in the data * set are still considered up to date and will not be rebound, though their positions * may be altered.

* * @param positionStart Previous position of the first item that was removed * @param itemCount Number of items removed from the data set */ public final void notifyItemRangeRemoved(int positionStart, int itemCount) { mObservable.notifyItemRangeRemoved(positionStart, itemCount); }

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

 public void removeItemAtPosition(int position) { items.remove(position); } 

И назовите это в своем fragmentе или активности следующим образом:

 adapter.removeItemAtPosition(position); 

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

 public void removeItem(@NonNull Object object) { mDataSetList.remove(object); notifyDataSetChanged(); } 

Вот несколько дополнительных примеров. См. Мой полный ответ для примеров добавления и удаления диапазона.

Добавить отдельный элемент

Добавьте «Свиньи» в индекс 2 .

Вставить отдельный элемент

 String item = "Pig"; int insertIndex = 2; data.add(insertIndex, item); adapter.notifyItemInserted(insertIndex); 

Удалить отдельный элемент

Удалите «Свиньи» из списка.

Удалить отдельный элемент

 int removeIndex = 2; data.remove(removeIndex); adapter.notifyItemRemoved(removeIndex); 
  String str = arrayList.get(position); arrayList.remove(str); MyAdapter.this.notifyDataSetChanged(); 

если вы хотите удалить элемент, вы должны сделать это: сначала удалите элемент:

 phones.remove(position); 

в следующем шаге вы должны уведомить адаптер recycler, что вы удаляете элемент по этому коду:

 notifyItemRemoved(position); notifyItemRangeChanged(position, phones.size()); 

но если вы измените элемент, сделайте следующее: сначала измените параметр своего объекта следующим образом:

 Service s = services.get(position); s.done = "Cancel service"; services.set(position,s); 

или новое это так:

 Service s = new Service(); services.set(position,s); 

затем сообщите об этом адаптеру вашего ресайклера, который вы изменяете по этому элементу:

 notifyItemChanged(position); notifyItemRangeChanged(position, services.size()); 

надеюсь, поможет вам.

  //////// set the position holder.cancel.setTag(position); ///// click to remove an item from recycler view and an array list holder.cancel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int positionToRemove = (int)view.getTag(); //get the position of the view to delete stored in the tag mDataset.remove(positionToRemove); notifyDataSetChanged(); } }); 

сделать интерфейс в пользовательский class адаптера и обработать событие click на просмотре recycler.

  onItemClickListner onItemClickListner; public void setOnItemClickListner(CommentsAdapter.onItemClickListner onItemClickListner) { this.onItemClickListner = onItemClickListner; } public interface onItemClickListner { void onClick(Contact contact);//pass your object types. } @Override public void onBindViewHolder(ItemViewHolder holder, int position) { // below code handle click event on recycler view item. holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { onItemClickListner.onClick(mContectList.get(position)); } }); } 

после определения адаптера и привязки к просмотру recycler, называемому ниже кода ..

  adapter.setOnItemClickListner(new CommentsAdapter.onItemClickListner() { @Override public void onClick(Contact contact) { contectList.remove(contectList.get(contectList.indexOf(contact))); adapter.notifyDataSetChanged(); } }); } 
  • Как удалить материал, напечатанный на консоль System.out.println ()?
  • Как основной stream, созданный Java
  • Как получить String Array из файла arrays.xml
  • Ошибка: (23, 17) Не удалось выполнить: junit: junit: 4.12
  • отображение AM и PM в маленькой букве после форматирования даты
  • Метод getText () должен быть вызван из streamа пользовательского интерфейса (Android Studio)
  • notifyDataSetChanged () делает обновление списка и прокручивает подсказки назад
  • Как создать формат BKS (BouncyCastle) Java Keystore, который содержит цепочку сертификатов клиента
  • Программно скрыть / показать Android Soft Keyboard
  • Ошибка: выполнение выполнено для задачи ': app: processDebugResources'. > java.io.IOException: не удалось удалить папку "" в андроид-студии
  • Получить имя устройства Android
  • Давайте будем гением компьютера.