Marcar todos los CheckBox de un ListVieW

Publicado por Alejandro Escario en

Hace una semana comentábamos el modo de crear un ListView para Android con, como mínimo, un CheckBox en cada fila de la lista. Este mini tutorial de hoy, en el que vamos a explicar como marcar de una todos los CheckBox de un ListView, vamos a basarnos en el contenido explicado en dicho artículo.

En principio la metodología parece sencilla, en nuestro fichero main.xml, además de declarar un ListView, declaramos en la parte inferior un CheckBox cuyo comportamiento determinaremos más adelante, de manera que el contenido del main.xml quedaría de la siguiente manera:

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <ListView
    	android:id="@+id/list"
    	android:layout_width="fill_parent"
    	android:layout_height="wrap_content"
        android:layout_weight="1"
        android:drawSelectorOnTop="false"/>
	<CheckBox
		android:id="@+id/chkSelectAll"
		android:text="@string/chkSelectAll"
		android:visibility="visible"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"/>
</LinearLayout>

Hasta aquí todo ha sido coser y cantar, de nuevo hemos de definir un fichero con el Layout de cada una de las filas de lo que será nuestro ListView, en nuestro caso item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_height="wrap_content"
	android:layout_width="fill_parent">
	<CheckBox
		android:id="@+id/chkItem"
		android:visibility="visible"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"/>
</LinearLayout>

Una vez que tenemos hecho esto nos bastará con definir el comportamiento de la clase principal para que al marchar el chkSelectAll se marquen todos los CheckBox de la lista, para ello en un principio, con poner el array que determina el valor de cada CheckBox a true o false, en función del caso, debería sernos suficiente. Para ello añadiríamos en el onCreate las liguientes lineas:

        chkAll = (CheckBox)findViewById(R.id.chkSelectAll);
        chkAll.setOnCheckedChangeListener(new OnCheckedChangeListener(){
			@Override
			public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
				for (int i = 0; i < adapter.getItemsLength(); i++) {
    	                                adapter.set(i, b);
    	                        }
			}
        });

El problema nos lo encontramos cuando lo que queremos es que además de marcarlos en el sistema queremos que se visualicen los CheckBox marcados directamente, para ello, lo que podemos hacer (AVISO: es una solución un poco cutre y simplemente para salir del paso) es reasignar el adaptador, para lo que después del for podríamos añadir las siguientes lineas:

        int pos = list.getFirstVisiblePosition();
    	list.setAdapter(adapter);
    	list.setSelection(pos);

Si ahora compilamos y ejecutamos el código podremos observar como el comportamiento es el deseado.