Diseño Android: Pull To Refresh con SwipeRefreshLayout

android

El patrón de diseño Swipe To Refresh, más conocido como Pull To Refresh, puede ser considerado como el mecanismo estándar en aplicaciones móviles para actualizar el contenido de un listado o grid de datos con los elementos más recientes los cuales son añadidos en la parte superior del listado. Al deslizarse el listado hacia abajo y mostrarse el primer elemento, si el usuario intenta seguir deslizando un poco más (a veces se muestra un mensaje informando al usuario de esta posibilidad) se procede a la obtención de nuevos datos mostrando un Progress Dialog indeterminado.

android pull to refresh

Google incluye este patrón en Material Design y proporciona, a través de la librería de compatibilidad, un ViewGroup denominado SwipeRefreshLayout para implementar esta funcionalidad. SwipeRefreshLayout será el padre de un View deslizable, como por ejemplo ListView, ScrollView o RecyclerView, y mediante un listener nos informará del gesto Swipe To Refresh para que actuemos en consecuencia. También proporciona un indicador de la actualización.

Para dotar a un listado o similar de la funcionalidad Pull To Refresh seguimos los siguientes pasos

  1. Incluir la librería de compatibilidad (v4) en el proyecto. En Android Studio/Gradle se añade la siguiente depedencia.
    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        compile 'com.android.support:support-v4:22.2.1'
    }
    

    Para más información sobre la importación de librerías en Eclipse ADT y Android Studio, consultar este artículo.

  2. Establecer SwipeRefreshLayout como padre de la vista a actualizar. En este tutorial se utilizará el ejemplo de Android Recycler View: Listas.
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">
    
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?attr/colorPrimary"
            android:elevation="4dp"
            android:minHeight="?attr/actionBarSize"
            app:theme="@style/ThemeOverlay.AppCompat.ActionBar" />
    
        <android.support.v4.widget.SwipeRefreshLayout
            android:id="@+id/swipeLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <android.support.v7.widget.RecyclerView
                android:id="@+id/recyclerView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scrollbars="vertical" />
    
        </android.support.v4.widget.SwipeRefreshLayout>
    
    </LinearLayout>
    
  3. En la Activity, se implementa el evento SwipeRefreshLayout.OnRefreshListener.
     swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeLayout);
            swipeRefreshLayout.setOnRefreshListener(
                    new SwipeRefreshLayout.OnRefreshListener() {
                        @Override
                        public void onRefresh() {
                            asyncTask = new BackgroundTask();
                            Void[] params = null;
                            asyncTask.execute(params);
                        }
                    });
    

    La obtención de los nuevos datos debe realizarse de forma asíncrona utilizando por ejemplo AsyncTask o Runnable. En el ejemplo se simula el tiempo que tarda la obtención de los datos con un Thread.sleep() y se añaden nuevos colores al RecyclewView sólo en caso que queden algunos por mostrar. Por último, se oculta el indicador de actualización que muestra automáticamente SwipeRefreshLayout.

     private class BackgroundTask extends AsyncTask<Void, Void, Void> {
    
            @Override
            protected Void doInBackground(Void... params) {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return null;
            }
    
            @Override
            protected void onPostExecute(Void aVoid) {
                int sizePrev = colors.size();
                MainActivity.this.loadMoreColors();
                recyclerView.getAdapter().notifyItemRangeInserted(0, colors.size() - sizePrev);
                //hides the refresh indicator
                MainActivity.this.swipeRefreshLayout.setRefreshing(false);
                if (colors.size() > sizePrev) {
                    recyclerView.scrollToPosition(0);
                }
            }
    
            @Override
            protected void onCancelled() {
                swipeRefreshLayout.setRefreshing(false);
            }
        }
    
  4. Opcionalmente se puede definir el color del indicador de la actualización. El método setColorSchemeResources recibe una lista de los colores que se irán aplicando, de forma circular, en cada nueva vuelta del circulo del indicador.
    swipeRefreshLayout.setColorSchemeResources(R.color.primary, R.color.amber...
    

    La siguiente animación muestra la aplicación de estos colores
    SwipeRefreshLayout Indicator

    1. Por último, simplemente comentar que se puede habilitar/deshabilitar la operación Swipe To Refresh con el método setEnabled.



      Código de ejemplo

      El proyecto de ejemplo para Android Studio se encuentra disponible en GitHub. Para más información sobre cómo utilizar GitHub, consultar este artículo.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: