Estado de comprobación de ListView Viewholder

Tengo algunos problemas con mi adaptador personalizado ListView (y su nuevo viewHolder implementado). Tengo un ListView con una casilla de verificación para cada elemento (nada nuevo aquí). El problema es que si hay más de 9 elementos en mi lista, cuando compruebo la primera casilla, la décima será automáticamente marcada (igual para la segunda con la undécima), como si hubiera un oyente para ambos ítem Cree que es el caso de alguna manera).

He leído sobre la cuestión de la posición con listView, ver el reciclaje y la forma ViewHolder para resolverlo aquí: ¿Cómo puedo hacer que mi ArrayAdapter siga el patrón ViewHolder?

Pero probablemente hice algo mal porque no está funcionando …

public class PresenceListAdapter extends SimpleAdapter { private LayoutInflater inflater; private List<Integer> ids; private List<String> statuts; public PresenceListAdapter (Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to, List<Integer> ids, List<String> statuts) { super (context, data, resource, from, to); inflater = LayoutInflater.from (context); this.ids = ids; this.statuts= statuts; } @Override public Object getItem (int position) { return super.getItem (position); } @Override public View getView (int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = inflater.inflate (R.layout.list_text_checkbox, null); holder = new ViewHolder(); holder.btn = (Button) convertView.findViewById(R.id.btnRetard); holder.check = (CheckBox) convertView.findViewById(R.id.checkPresent); if (statuts.get(position).equals("P")) { Drawable img = inflater.getContext().getResources().getDrawable(android.R.drawable.presence_online); holder.btn.setCompoundDrawablesWithIntrinsicBounds( img, null, null, null ); holder.btn.setEnabled(true); holder.check.setChecked(true); } else if(statuts.get(position).equals("R")) { Drawable img = inflater.getContext().getResources().getDrawable(android.R.drawable.presence_away); holder.btn.setCompoundDrawablesWithIntrinsicBounds( img, null, null, null ); holder.btn.setEnabled(true); holder.check.setChecked(true); } else { Drawable img = inflater.getContext().getResources().getDrawable(android.R.drawable.presence_invisible); holder.btn.setCompoundDrawablesWithIntrinsicBounds( img, null, null, null ); holder.check.setChecked(false); } convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } int id = ids.get(position); if(id != 0) { holder.check.setTag(id); holder.btn.setTag(id); } return super.getView (position, convertView, parent); } static class ViewHolder { Button btn; CheckBox check; } 

Y mi oyente: public void changerPresent (View v) {

  CheckBox checkPresent = (CheckBox) v; int idPersonne = (Integer) checkPresent.getTag(); View parent = (View)v.getParent(); Button btn = (Button) parent.findViewById(R.id.btnRetard); if(checkPresent.isChecked()) { gestion.updatePresence(idPersonne, idSeance, "P"); btn.setEnabled(true); setBtnRetardPresent(btn); } else { gestion.updatePresence(idPersonne, idSeance, "A"); btn.setEnabled(false); setBtnRetardAbsent(btn); } } 

Agradecería cualquier ayuda en este punto, estoy trabajando en esto por horas ahora.

Muchas gracias.

Así es como lo hice funcionar:

En primer lugar, necesita una matriz independiente para su estado marcado. Tiene que ser del mismo tamaño que el getCount() su adaptador getCount() .

Luego, en su getView, el setOnCheckedChangedListener de su casilla de verificación debe PRECEED sus sentencias checkbox.setChecked.

ejemplo:

 holder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { isChecked[position] = isChecked; } }); holder.checkBox.setChecked(isChecked[position]); 

Debe establecer el estado CheckedBox fuera de la inicialización de ViewHolder, como el código siguiente:

 if (convertView == null) { viewHolder = new ViewHolder(); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } viewHolder.checkedBox.setChecked(); 

BTW: utiliza SparseBooleanArray en lugar de dos listas para almacenar el estado CheckedBox.

El problema es debido al hecho de que listview recicla las vistas

Así que en el método getView( )

  if (convertView == null) { ........ } else { holder = (ViewHolder) convertView.getTag(); } // Uncheck needed boxes here... You need to implement your logic if( 'position' is checked earlier) holder.check.setChecked(true); else holder.check.setChecked(false); 

Es necesario escribir el código para administrar el estado de la vista si el convertidor no es nulo, ya que es una vista ya utilizada que puede estar marcando casillas de verificación.

  • Eliminación de la "casilla" de la casilla de verificación en Android
  • Cómo obtener los elementos de la lista seleccionada de un Listview con checkBox y Adaptador personalizado?
  • Cómo cambiar la casilla de verificación tick color en android
  • Cómo actualizar el contenido de una sola fila en mi ListView utilizando OnItemClick
  • Establecer la posición dinámica de brindis en una vista
  • Cómo desmarcar una casilla de verificación de Android marcada
  • Cambiar el valor de la casilla de verificación sin activar onCheckChanged
  • Cómo puedo obtener todos los elementos de la lista seleccionada mediante la casilla de verificación
  • Se comprueba un elemento incorrecto al filtrar ListView en android
  • Creación de una casilla de verificación de tres estados en android
  • Imagen personalizada de la casilla de verificación android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.