Using notifyItemRemoved o notifyDataSetChanged con RecyclerView en Android

Estoy creando una lista de tarjetas para mostrar usando el RecyclerView, donde cada tarjeta tiene un botón para quitar esa tarjeta de la lista.

Cuando utilizo notifyItemRemoved () para quitar la tarjeta en el RecyclerView, elimina el elemento y anima bien, pero los datos de la lista no se actualizan correctamente.

Si en vez de eso, cambia a notifyDataSetChanged () entonces los artículos en la lista se quitan y se ponen al día correctamente, pero entonces las tarjetas no animan.

¿Alguien tiene alguna experiencia en el uso de notifyItemRemoved () y saber por qué se comporta de manera diferente que notifyDataSetChanged?

Aquí hay algunos peiece de código que estoy usando:

private List<DetectedIssue> issues = new ArrayList<DetectedIssue>(); @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { // - get element from your dataset at this position // - replace the contents of the view with that element if(position >0){ RiskViewHolder riskHolder = (RiskViewHolder)holder; final int index = position - 1; final DetectedIssue anIssue = issues.get(index); riskHolder.button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { int index = issues.indexOf(anIssue); issues.remove(anIssue); notifyItemRemoved(index); //notifyDataSetChanged(); } catch (SQLException e) { e.printStackTrace(); } } }); } } @Override public int getItemCount() { return (issues.size()+1); } 

7 Solutions collect form web for “Using notifyItemRemoved o notifyDataSetChanged con RecyclerView en Android”

Utilice notifyItemRangeChanged (position, getItemCount ()); Después de notifyItemRemoved (posición);
No es necesario usar el índice, solo use la posición. Vea el código abajo.

 private List<DetectedIssue> issues = new ArrayList<DetectedIssue>(); @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { // - get element from your dataset at this position // - replace the contents of the view with that element if(position >0){ RiskViewHolder riskHolder = (RiskViewHolder)holder; riskHolder.button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { issues.remove(position); notifyItemRemoved(position); //this line below gives you the animation and also updates the //list items after the deleted item notifyItemRangeChanged(position, getItemCount()); } catch (SQLException e) { e.printStackTrace(); } } }); } } @Override public int getItemCount() { return issues.size(); } 

Intentó

 public void removeItem(int position) { this.taskLists.remove(position); notifyItemRemoved(position); notifyItemRangeChanged(position, getItemCount() - position); } 

Y trabajando como un encanto.

Mi error, notifyItemChanged (posición) está indefenso, el elemento de posición se puede quitar, y el elemento de posición + 1 está bien, pero los elementos empiezan desde la posición + 2, obtendrá una Excepción, use notifyItemRangeChanged (position, getItemCount ()); Después de notifyItemRemoved (posición);

Me gusta esto:

 public void removeData(int position) { yourdatalist.remove(position); notifyItemRemoved(position); notifyItemRangeChanged(position,getItemCount()); } 

Como @pskink sugirió que se suponía que era (index + 1) en mi caso con notifyItemRemoved(index+1) , probablemente porque estoy reservando el índice superior ie position=0 para un encabezado.

Puede utilizar getLayoutPosition() del RecyclerView.ViewHolder

getLayoutPosition() proporciona la posición exacta del elemento en el diseño y el código es

 holder.removeButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //Position for remove int modPosition= holder.getLayoutPosition(); //remove item from dataset numbers.remove(modPosition); //remove item from recycler view notifyItemRemoved(modPosition); } }); 
 **my solution looks like this** this way is unnecessary to use the heavy method: //notifyItemRangeChanged(xx,xx) /** * * recyclerView的item中的某一个view,获取其最外层的viewParent,也就是item对应的layout在adapter中的position * * @param recyclerView * @param view:can be the deep one inside the item,or the item itself . * @return */ public static int getParentAdapterPosition(RecyclerView recyclerView, View view, int parentId) { if (view.getId() == parentId) return recyclerView.getChildAdapterPosition(view); View viewGroup = (View) view.getParent(); if (viewGroup != null && viewGroup.getId() == parentId) { return recyclerView.getChildAdapterPosition(viewGroup); } //recursion return getParentAdapterPosition(recyclerView, viewGroup, parentId); } //wherever you set the clickListener . holder.setOnClickListener(R.id.rLayout_device_item, deviceItemClickListener); holder.setOnLongClickListener(R.id.rLayout_device_item, deviceItemLongClickListener); @Override public boolean onLongClick(View v) { final int position = ViewUtils.getParentAdapterPosition(rVDevicesList, v, R.id.rLayout_device_item); return true; } 

Debe añadir eliminar el listener en la clase ViewHolder

  button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onCancel(getAdapterPosition()); } }); private void onCancel(int position) { if (position >= issues.size()) return; issues.remove(position); notifyItemRemoved(position); } 
  • ¿Qué es la contraparte de RecyclerView.Adapter de ListView.Adpater.isEnabled ()
  • No se puede agregar vista vacía abajo Recyclerview
  • ¿Cómo utilizar ItemAnimator en un RecyclerView?
  • ¿Hay alguna forma de calcular la posición final de desplazamiento
  • Recyclerview dolorosamente lento para cargar imágenes en caché de Picasso
  • StaggeredGridLayoutManager reordena los elementos
  • Expandiendo / Colapsando CardView con un gesto de clic o de deslizamiento (Android)?
  • Cómo filtrar un RecyclerView con un SearchView
  • LinearLayoutManager setReverseLayout () == true pero pila de elementos desde la parte inferior
  • Android notifyItemRangeInserted deshabilitar autoscroll
  • RecyclerView onItemClicked devolución de llamada
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.