Listview con un adaptador personalizado que contiene CheckBoxes

Tengo un ListView que utiliza un adaptador de encargo como se muestra:

private class CBAdapter extends BaseAdapter implements OnCheckedChangeListener{ Context context; public String[] englishNames; LayoutInflater inflater; CheckBox[] checkBoxArray; LinearLayout[] viewArray; private boolean[] checked; public CBAdapter(Context con, String[] engNames){ context=con; englishNames=engNames; inflater=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); checked= new boolean[englishNames.length]; for(int i=0; i<checked.length; i++){ checked[i]=false; //Toast.makeText(con, checked.toString(),Toast.LENGTH_SHORT).show(); } checkBoxArray = new CheckBox[checked.length]; viewArray = new LinearLayout[checked.length]; } public int getCount() { return englishNames.length; } public Object getItem(int position) { // TODO Auto-generated method stub return null; } public long getItemId(int position) { // TODO Auto-generated method stub return 0; } public View getView(int position, View convertView, ViewGroup parent) { if(viewArray[position] == null){ viewArray[position]=(LinearLayout)inflater.inflate(R.layout.record_view_start,null); TextView tv=(TextView)viewArray[position].findViewById(R.id.engName); tv.setText(englishNames[position]); checkBoxArray[position]=(CheckBox)viewArray[position].findViewById(R.id.checkBox1); } checkBoxArray[position].setChecked(checked[position]); checkBoxArray[position].setOnCheckedChangeListener(this); return viewArray[position]; } public void checkAll(boolean areChecked){ for(int i=0; i<checked.length; i++){ checked[i]=areChecked; if(checkBoxArray[i] != null) checkBoxArray[i].setChecked(areChecked); } notifyDataSetChanged(); } public void onCheckedChanged(CompoundButton cb, boolean isChecked) { for(int i=0; i<checked.length; i++){ if(cb == checkBoxArray[i]) checked[i]=isChecked; } } public boolean itemIsChecked(int i){ return checked[i]; } } 

Los diseños son bastante simples, así que no los publicaré a menos que alguien piensa que son relevantes.

El problema es que algunos de los CheckBox no responden. Parece que son los que son visibles cuando se muestra el diseño por primera vez. Cualquiera que tenga que desplazarse hacia abajo para funcionar como se esperaba.

Cualquier puntuación apreciada.

Su código de la respuesta funciona, pero es ineficiente (puede ver esto, sólo desplácese por el ListView y compruebe el Logcat para ver el recolector de basura haciendo su trabajo). Un método getView mejorado que recicle las vistas es el siguiente:

 @Override public View getView(int position, View convertView, ViewGroup parent) { LinearLayout view = (LinearLayout) convertView; if (view == null) { view = (LinearLayout) inflater.inflate(R.layout.record_view_start, parent, false); } TextView tv = (TextView) view.findViewById(R.id.engName); tv.setText(getItem(position)); CheckBox cBox = (CheckBox) view.findViewById(R.id.checkBox1); cBox.setTag(Integer.valueOf(position)); // set the tag so we can identify the correct row in the listener cBox.setChecked(mChecked[position]); // set the status as we stored it cBox.setOnCheckedChangeListener(mListener); // set the listener return view; } OnCheckedChangeListener mListener = new OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { mChecked[(Integer)buttonView.getTag()] = isChecked; // get the tag so we know the row and store the status } }; 

En cuanto a su código de su pregunta, al principio pensé que estaba mal debido a la forma en que la configuración de las filas, pero no veo por qué el adaptador tendrá ese comportamiento como se desprendió la vista de la fila de la lista. Además, incluso probé el código y funciona muy bien con respecto a CheckBoxes (pero con manejo de memoria muy pobre). Tal vez usted está haciendo algo más que hace que el adaptador no funcione?

Permítanme decir primero que han tirado una de las principales ventajas de usar un adaptador: Vistas reutilizables. Sostener una referencia dura a cada View creada tiene un alto riesgo de golpear el techo de la memoria. Debería volver a convertView cuando no sea nulo y crear su vista cuando convertView sea ​​null. Hay muchos tutoriales en torno a los que te muestran cómo hacerlo.

Las vistas utilizadas en un adaptador suelen tener un OnClickListener asociado a ellos por la View primaria para que pueda establecer un OnItemClickListener en ListView . Esto sustituirá a cualquier oyente táctil en las vistas individuales. Pruebe a configurar android:clickable="true" en el CheckBox en XML.

Esto puede no ser la solución más elegante o eficiente, pero funciona para mi situación. Por alguna razón, intentar reutilizar las vistas, ya sea a partir de una serie de vistas o mediante convertView hace que todo vaya wobbley y los CheckBoxes no responden.

Lo único que funcionó fue crear una nueva View everytime getView () se llama.

  public View getView(final int position, View convertView, ViewGroup parent) { LinearLayout view; view=(LinearLayout)inflater.inflate(R.layout.record_view_start,null); TextView tv=(TextView)view.findViewById(R.id.engName); tv.setText(englishNames[position]); CheckBox cBox=(CheckBox)view.findViewById(R.id.checkBox1); cBox.setChecked(checked[position]); cBox.setOnCheckedChangeListener(new OnCheckedChangeListener(){ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { checked[position]=isChecked; } }); return view; } 

Encontrar esta solución también fue obstaculizada por el hecho de que yo estaba llamando a un onCheckedChangedListener definido por separado, que luego identificó qué CheckBox por id, en lugar de tener un nuevo oyente para cada CheckBox.

Todavía no he marcado esto como la respuesta correcta, ya que estoy esperando que los demás pueden tener alguna información sobre la reconstrucción de la vista bastante inútil cada vez.

  • La imagen personalizada de CheckBox se corta
  • Cómo establecer la casilla de verificación en el lado derecho del texto
  • El clic de Listitem no funciona con las casillas de verificación Android
  • Cómo personalizar (aumentar el tamaño) de la casilla de verificación en Android
  • 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
  • Cómo desmarcar una casilla de verificación de Android marcada
  • Cambiar el valor de la casilla de verificación sin activar onCheckChanged
  • Seleccione sólo una casilla de verificación
  • Imagen personalizada de la casilla de verificación android
  • Android: checkbox listener
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.