Eliminación de elementos de un ListView mediante un BaseAdapter personalizado
Estoy utilizando un BaseAdapter personalizado para mostrar elementos en un ListView. Los elementos son sólo cadenas contenidas en un ArrayList.
Los elementos de la lista tienen un botón de borrado en ellos (X rojo grande), y me gustaría quitar el elemento de la ArrayList, y notificar el ListView para actualizarse.
- ListView en SlidingDrawer pierde foco después de onResume
- ListView se desplaza hacia arriba cuando EditText crece
- Longitud androide de la barra de desplazamiento con diversos tamaños del artículo
- ¿Cómo activar el desplazamiento rápido (pulgar) en el menú desplegable de Android Spinner?
- Checkbox auto call onCheckedChange cuando se desplaza el listview?
Sin embargo, cada implementación que he probado obtiene números de posición misteriosa que se le asignan, por lo que al hacer clic en el botón de borrado del elemento 2, se eliminará el elemento 5. Parece ser casi enteramente al azar.
Una cosa a tener en cuenta es que los elementos pueden repetirse, pero deben mantenerse en el mismo orden. Por ejemplo, puedo tener "irlandés" dos veces, como elementos 3 y 7.
Mi código está abajo:
private static class ViewHolder { TextView lang; int position; } public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = mInflater.inflate(R.layout.language_link_row, null); holder = new ViewHolder(); holder.lang = (TextView)convertView.findViewById(R.id.language_link_text); holder.position = position; final ImageView deleteButton = (ImageView) convertView.findViewById(R.id.language_link_cross_delete); deleteButton.setOnClickListener(this); convertView.setTag(holder); deleteButton.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.lang.setText(mLanguages.get(position)); return convertView; }
Más tarde intento recuperar la posición del elemento eliminado agarrando la etiqueta, pero siempre es la posición equivocada en la lista. No hay un patrón notable en la posición dada aquí, siempre parece aleatorio.
// The delete button's listener public void onClick(View v) { ViewHolder deleteHolder = (ViewHolder) v.getTag(); int pos = deleteHolder.position; ... ... ... }
Estaría muy feliz de eliminar el elemento de la ArrayList y tener la actualización ListView en sí, pero la posición que estoy recibiendo es incorrecta, así que no puedo hacer eso.
Tenga en cuenta que al principio, tenía el deleteButton clickListener dentro del método getView y usé 'position' para eliminar el valor, pero tuve el mismo problema.
Cualquier sugerencia apreciada, esto es realmente irritante para mí.
- Mantener el foco en TextView después de notifyDatasetChanged () fue llamado en listview personalizado?
- Idea sobre la implementación del siguiente menú emergente en ListView
- Cómo aplicar la animación de diseño de Android sólo a los niños por encima de un cierto índice?
- Expanda CardView dentro de RecyclerView como nueva actividad como Inbox de Google Android
- Custom ListView y el menú contextual. ¿Cómo conseguirlo?
- Android listview mensaje vacío con encabezado
- Adaptador de actualización de animación ListView android
- Cómo agregar el diseño personalizado a Arrayadapter?
Usted tiene que fijar la posición cada vez. Su implementación sólo establece la posición en la creación de la vista. Sin embargo, cuando la vista se recicla (cuando convertView no es nulo), la posición no se establecerá en el valor correcto.
public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = mInflater.inflate(R.layout.language_link_row, null); holder = new ViewHolder(); holder.lang = (TextView)convertView.findViewById(R.id.language_link_text); final ImageView deleteButton = (ImageView) convertView.findViewById(R.id.language_link_cross_delete); deleteButton.setOnClickListener(this); convertView.setTag(holder); deleteButton.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.lang.setText(mLanguages.get(position)); holder.position = position; return convertView; }
Es necesario implementar la interfaz OnItemClickListener y eliminar el elemento del método onItemClick, un parámetro del método es la posición.
Mi solución final fue usar la respuesta aceptada por Greg y lo siguiente:
-
Almacene los soportes en un HashMap, con las posiciones del artículo como las llaves (esto se inicializa como vacío en el constructor)
MHoldMap privado de los mHolders;
-
Utilice esto como el método onClickListener:
public void onClick(View v) { ViewHolder deleteHolder = (ViewHolder) v.getTag(); int pos = deleteHolder.position; mHolders.remove(pos);
public void onClick(View v) { ViewHolder deleteHolder = (ViewHolder) v.getTag(); int pos = deleteHolder.position; mHolders.remove(pos);
ViewHolder currentHolder; // Shift 'position' of remaining languages // down since 'pos' was deleted for(int i=pos+1; i<getCount(); i++){ currentHolder = mHolders.get(i); currentHolder.position = i-1; } mLanguages.remove(pos); notifyDataSetChanged(); }
[Disculpe el formato extraño. La incrustación de código no funciona correctamente]
- Uso de la API Google Maps de Google android v2 como visor de mosaicos sin conexión: ¿es posible?
- El método de Android AppWidgetManager updateAppWidget falla en establecer intents, cargar datos. Y sucede al azar