java - studio - Android RecyclerVer adición y eliminación de elementos
recyclerview dependency (16)
Tengo un RecyclerView con un cuadro de texto TextView y un botón de visualización ImageView. Tengo un botón fuera de la vista de reciclaje que hace que el botón de cruz ImageView sea visible / desaparecido.
Estoy buscando eliminar un elemento de la vista del reciclador, cuando ese elemento cruza el botón ImageView.
Mi adaptador:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> implements View.OnClickListener, View.OnLongClickListener {
private ArrayList<String> mDataset;
private static Context sContext;
public MyAdapter(Context context, ArrayList<String> 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);
}
}
}
Mi diseño es:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:id="@+id/layout">
<TextView
android:id="@+id/nameTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:padding="5dp"
android:background="@drawable/greyline"/>
<ImageView
android:id="@+id/crossButton"
android:layout_width="16dp"
android:layout_height="16dp"
android:visibility="gone"
android:layout_marginLeft="50dp"
android:src="@drawable/cross" />
</LinearLayout>
¿Cómo puedo obtener algo como un onClick que funcione para mi CrossButton ImageView? ¿Hay una mejor manera? ¿Tal vez cambiar todo el elemento al hacer clic en quitar el elemento? La vista de reciclaje muestra una lista de ubicaciones que deben editarse. Cualquier consejo técnico o comentario / sugerencia sobre la mejor implementación sería muy apreciado.
Aquí hay algunos ejemplos visuales suplementarios. Vea mi respuesta más completa para ver ejemplos de agregar y quitar un rango.
Añadir elemento individual
Agregue "Pig" en el índice
2
.
String item = "Pig";
int insertIndex = 2;
data.add(insertIndex, item);
adapter.notifyItemInserted(insertIndex);
Eliminar un solo artículo
Eliminar "Pig" de la lista.
int removeIndex = 2;
data.remove(removeIndex);
adapter.notifyItemRemoved(removeIndex);
El problema que tuve fue que estaba eliminando un elemento de la lista que ya no estaba asociado con el adaptador para asegurarme de que está modificando el adaptador correcto, puede implementar un método como este en su adaptador:
public void removeItemAtPosition(int position) {
items.remove(position);
}
Y llámalo en tu fragmento o actividad así:
adapter.removeItemAtPosition(position);
En caso de que alguien quiera implementar algo como esto en la clase Main en lugar de la clase Adapter, puede usar `public void removeAt (int position) {peopleListUser.remove (position);
friendsListRecycler.getAdapter().notifyItemRemoved(position);
friendsListRecycler.getAdapter().notifyItemRangeChanged(position, peopleListUser.size());
}`
donde friendsListRecycler es el nombre del adaptador
En caso de que se pregunte como yo, ¿dónde podemos obtener la posición del adaptador en el método getadapterposition (); está en el objeto viewholder.así que tienes que poner tu código así
mdataset.remove(holder.getadapterposition());
En primer lugar, el elemento debe eliminarse de la lista.
mDataSet.remove(getAdapterPosition());
entonces:
notifyItemRemoved(getAdapterPosition());
notifyItemRangeChanged(getAdapterPosition(),mDataSet.size());
He hecho algo similar
En su
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());
}
Espero que esto ayude.
Editar:
getPosition()
está en desuso ahora, use
getAdapterPosition()
lugar.
Intenté todas las respuestas anteriores, pero insertar o eliminar elementos para la vista del reciclador causa problemas con la posición en el conjunto de datos.
Terminé usando
delete(getAdapterPosition());
dentro del viewHolder que funcionó muy bien para encontrar la posición de los artículos.
Para Método
onBindViewHolder
Escriba este Código
holder.remove.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Cursor del=dbAdapter.ExecuteQ("delete from TblItem where Id="+values.get(position).getId());
values.remove(position);
notifyDataSetChanged();
}
});
Posiblemente una respuesta duplicada pero bastante útil para mí.
Puede implementar el método que se proporciona a continuación en
RecyclerView.Adapter<RecyclerView.ViewHolder>
y puede usar este método según sus requisitos, espero que funcione para usted
public void removeItem(@NonNull Object object) {
mDataSetList.remove(object);
notifyDataSetChanged();
}
Si no especifica correctamente lo que sucede al agregar / eliminar elementos, los elementos secundarios de RecyclerView se animan sin responder / se introducen errores
public void remove(int position) {
dataset.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, dataset.size());
}
En cambio, el siguiente código reproducirá la animación solo en el elemento secundario que se está eliminando, y para mí dejó de arrojar
IndexOutOfBoundException
s, marcado por el depurador como "inconsistencia de datos"
void remove(int position) {
dataset.removeAt(position);
notifyItemChanged(position);
notifyItemRangeRemoved(position, 1);
}
Si profundizamos en la clase
RecyclerView
podemos encontrar un trozo de documentación que explica que el segundo parámetro que tenemos que pasar es el número de elementos que se eliminan del conjunto de datos, no el número total de elementos.
/**
* Notify any registered observers that the <code>itemCount</code> items previously
* located at <code>positionStart</code> have been removed from the data set. The items
* previously located at and after <code>positionStart + itemCount</code> may now be found
* at <code>oldPosition - itemCount</code>.
*
* <p>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.</p>
*
* @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);
}
convertir la interfaz en una clase de adaptador personalizada y gestionar el evento de clic en la vista de reciclador.
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));
}
});
}
después de definir el adaptador y vincularlo a la vista del reciclador llamado código a continuación.
adapter.setOnItemClickListner(new CommentsAdapter.onItemClickListner() {
@Override
public void onClick(Contact contact) {
contectList.remove(contectList.get(contectList.indexOf(contact)));
adapter.notifyDataSetChanged();
}
});
}
si desea eliminar el elemento, debe hacer esto: primero elimine el elemento:
phones.remove(position);
en el siguiente paso, debe notificar a su adaptador de reciclador que elimina un artículo mediante este código:
notifyItemRemoved(position);
notifyItemRangeChanged(position, phones.size());
pero si cambia un elemento, haga esto: primero cambie un parámetro de su objeto como este:
Service s = services.get(position);
s.done = "Cancel service";
services.set(position,s);
o nuevo así:
Service s = new Service();
services.set(position,s);
luego notifique a su adaptador de reciclador que modifica un artículo con este código:
notifyItemChanged(position);
notifyItemRangeChanged(position, services.size());
La esperanza te ayuda.
si todavía no se eliminó el elemento, use este método mágico :)
private void deleteItem(int position) {
mDataSet.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, mDataSet.size());
holder.itemView.setVisibility(View.GONE);
}
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private Context context;
private List<cardview_widgets> list;
public MyAdapter(Context context, List<cardview_widgets> list) {
this.context = context;
this.list = list;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(this.context).inflate(R.layout.fragment1_one_item,
viewGroup, false);
return new MyViewHolder(view);
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
TextView txt_value;
TextView txt_category;
ImageView img_inorex;
ImageView img_category;
TextView txt_date;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
txt_value = itemView.findViewById(R.id.id_values);
txt_category = itemView.findViewById(R.id.id_category);
img_inorex = itemView.findViewById(R.id.id_inorex);
img_category = itemView.findViewById(R.id.id_imgcategory);
txt_date = itemView.findViewById(R.id.id_date);
}
}
@NonNull
@Override
public void onBindViewHolder(@NonNull final MyViewHolder myViewHolder, int i) {
myViewHolder.txt_value.setText(String.valueOf(list.get(i).getValuee()));
myViewHolder.txt_category.setText(list.get(i).getCategory());
myViewHolder.img_inorex.setBackgroundColor(list.get(i).getImg_inorex());
myViewHolder.img_category.setImageResource(list.get(i).getImg_category());
myViewHolder.txt_date.setText(list.get(i).getDate());
myViewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
list.remove(myViewHolder.getAdapterPosition());
notifyDataSetChanged();
return false;
}
});
}
@Override
public int getItemCount() {
return list.size();
}}
Espero que esto te ayude.
String str = arrayList.get(position);
arrayList.remove(str);
MyAdapter.this.notifyDataSetChanged();
//////// 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();
}
});