Swipe to Refresh en Android, como implementarlo correctamente

Uno de los patrones de diseño más útiles en Android es el gesto «Swipe to Refresh». El layout SwipeRefresh es básicamente un viewgroup que puede contener una objeto del tipo view que pueda hacer scroll, lo cual lo reduce básicamente a un scrollview, un gridview o un listview.

Lo que hace el layout SwipeToRefresh es gestionar los eventos que suceden al realizar el gesto de «tirar» de la vista con scroll hacia abajo. La vista se desplaza ligeramente, y rebota hacia arriba. En ese momento se invocan el método que hayamos definido para actualizar la información que mostramos en nuestra interfaz, mientras se visualiza una barra de progreso indeterminada en la parte superior.

Este patrón de diseño podemos encontrarlo en las ultimas apps de Google, por ejemplo Gmail o Google Now. El objetivo del patrón de diseño es eliminar la necesidad de una accion en algún menú o mediante algun icono en la Action Bar para refrescar la interfaz, descargando asi lal interfaz de contenido.

Implementarlo no es demasiado dificil, y tan solo hay que tener un detalle en cuenta cuando lo implementamos para un ListView o GridView.

Lo que hay que hacer es incluir nuestra ListView o GridView como hija de un ViewGroup SwipeToRefresh. La Activity o Fragment que corresponda a dicho layout, debe implementar la interfaz  SwipeRefreshLayout.OnRefreshListener. De tal manera que cuando realizamos el gesto de swipe, se invoca el metodo onRefresh de dicha interfaz, y en nuestra actividad o fragmento gestionamos el refresco de nuestra interfaz.

Sin embargo en la practica, aparece una dificultad un poco extraña: cuando ya tenemos nuestra lista cargada con elementos, observamos que al hacer scroll hacia arriba, se invoca tambien el callback onRefresh, con lo cual es imposible hacer scroll hacia arriba en una lista o grid.

Es curioso este comportamiento, a primera vista parece un bug, pero si tenemos en cuanta que el mismo viewgroup puede usarse para un ScrollView que no contenga una lista, entedemos por que funciona de esta manera.

En cualquier caso, basta con controlar el scroll de la lista, y desactivar el SwipeLayout cuando no estamos en el primer elemento, como veremos en el siguiente ejemplo.

activity_main.xml

MainActivity.java

Podeis descargar todo el proyecto de AndroidStudio de este ejemplo en el siguiente enlace:

Swipe To refresh Android Example