Uno de los patrones de
interacción que vemos cada vez más es el de Pull To Refresh.
Consiste en que el usuario realiza una acción de pull (tirar)
vertical hacia abajo para ejecutar una actualización del contenido
que esta viendo. Podemos verlo en aplicaciones móviles como gestores
de correo, Google+ o Facebook, es decir, en aplicaciones que muestran
contenido obtenido de forma remota y que por lo tanto necesita ser
actualizado. Es una forma sencilla e intuitiva de que el usuario
realice una actualización manual.
Aunque siempre puedes
implementar tu mismo este patrón, existen varias bibliotecas que nos
simplificarán la vida bastante. Yo he elegido
ActionBar-PullToRefresh. Es muy fácil de usar y de personalizar pero,
como se puede ver en su página de GitHub, ya no esta bajo
mantenimiento. Otro aspecto a tener en cuenta es que solo funciona
para versiones de Android igual o superiores a 4.0 (API 14).
Un
ejemplo sencillo:
Vamos a
aplicar el patrón sobre un Activity que despliega una lista, dejando
la
personalización para mas adelante y trabajando con los valores por defecto. En el caso de los Fragment la inicialización es un poco diferente pero los cambios son mínimos.
personalización para mas adelante y trabajando con los valores por defecto. En el caso de los Fragment la inicialización es un poco diferente pero los cambios son mínimos.
Primero
debemos incluir un PullToRefreshLayout como layout raíz de la
interfaz de nuestra Activity (MainActivity):
<uk.co.senab.actionbarpulltorefresh.library.PullToRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/my_ptr_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/my_listView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
</ListView>
</uk.co.senab.actionbarpulltorefresh.library.PullToRefreshLayout>
PullToRefreshLayout
solo funciona por defecto con:
- Clases que heredan de AbsListView (como ListView o GridView)
- ScrollView
- WebView
Para
cualquier otro tendremos que implementar nuestro propio ViewDelegate.
Ahora
inicializaremos PullToRefreshLayout en el código de MainActivity:
public
class
MainActivity extends
Activity{
private
View txt;
private
PullToRefreshLayout pullLayout;
private
final
OnRefreshListener onRefreshListener
=
new
OnRefreshListener(){
@Override
public
void
onRefreshStarted(View v){
//
Aqui realizaremos la actualización
}
};
@Override
protected
void
onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pullLayout
= (PullToRefreshLayout) findViewById(R.id.my_ptr_layout);
//
Inicializamos el PullToRefreshLayout
ActionBarPullToRefresh.from(this)
// Marcamos todos los hijos para que
puedan recibir la accion de pull
.allChildrenArePullable()
// Le indicamos el OnRefreshlistener
.listener(onRefreshListener)
// Terminamos la inicializacion
.setup(mPullToRefreshLayout);
//...
}
//...
}
Hay que
tener en cuenta que el método onRefreshStarted del listener
se ejecutará sobre la hebra principal así que lo mejor es que
lancemos algún tipo de AsyncTask o Loader. Para parar la animación
de actualización llamaremos al método setRefreshComplete
de nuestro PullToRefreshLayout:
@Override
public
void
onRefreshStarted(View view) {
new
AsyncTask<Void, Void, Void>() {
@Override
protected
Void doInBackground(Void... params) {
//Aqui
realizamos la actualización del contenido
return
null;
}
@Override
protected
void
onPostExecute(Void result) {
super.onPostExecute(result);
//...
pullLayout.setRefreshComplete();
}
}.execute();
}
Con
esto ya tenemos completo un ejemplo sencillo de uso de esta
biblioteca.
Personalización
Ya
hemos visto lo fácil que es usar la biblioteca. Ahora veremos lo
fácil que es cambiar el comportamiento de la barra de actualización.
En
la biblioteca tenemos la clase Options. Durante la inicialización
podemos darle una instancia de esta clase para indicarle distintos
elementos de configuración como:
- headerLayout: Layout (indicado por el identificador del recurso) que se usará para la barra de actualización.
- headerTransformer: El HeaderTransformer que se encargará de cambiar la barra de actualización según su estado (lo veremos mas adelante).
- headerInAnimation: Animación que se usará al mostrar la barra de actualización.
- headerOutAnimation: Animación que se usará al esconder la barra de actualización.
- refreshScrollDistance: Distancia de pulling necesaria para que se dispare la actualización. Se especifica en porcentaje (de 0.0 a 1.0) con respecto a la altura de la vista a la que se hará pull. Por ejemplo 0.5f significa que solo tenemos que recorrer la mitad de la altura para disparar la actualización.
- refreshOnUp: Por defecto la actualización se dispara cuando se recorre la distancia de pulling. Si activamos este elemento el usuario tendrá que levantar el dedo después de recorrerla, lo que le da la posibilidad de "arrepentirse" y volver atrás.
- refreshMinimize: Esconder la barra de actualización durante esta. Es útil cuando la actualización es muy larga y no queremos tapar indefinidamente el ActionBar.
- refreshMinimizeDelay: Es el tiempo que se esperará antes de esconder la barra de actualización.
Para
aplicar nuestras opciones tendremos que actualizar el código de
inicialización que hemos visto antes:
@Override
protected
void
onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pullLayout
= (PullToRefreshLayout) findViewById(R.id.my_ptr_layout);
Options
options = Options.create()
.scrollDistance(.5f)
.headerLayout(R.layout.customised_header)
.headerTransformer(new
CustomisedHeaderTransformer())
.build();
//
Inicializamos el PullToRefreshLayout
ActionBarPullToRefresh.from(this)
//
Le indicamos el objeto options a usar
.options(options)
.allChildrenArePullable()
.listener(onRefreshListener)
.setup(mPullToRefreshLayout);
//...
}
La
instancia de la clase CustomizedHeaderTransformer es la encargada de
actualizar la barra según el estado de la actualización. Hereda de
la clase abstracta HeaderTransformer y debe implementar los
siguientes métodos:
- boolean showHeaderView(): Se llama cuando la barra debe mostrarse.
- boolean hideHeaderView(): Se llama cuando la barra debe esconderse.
Además
de esos dos métodos se pueden implementar los siguientes:
- onViewCreated(Activity activity, View headerView): Se llama cuando se ha creado el View de la barra de actualización.
- activity: Activity a la que esta asociada la barra.
- headerView: Barra de actualización creada.
- onReset(): Se llama cuando la barra tiene que ser reiniciada.
- onPulled(float perc): Se llama cuando el usuario realiza la acción de pulling.
- perc: Porcentaje de distancia de pulling.
- onRefreshStarted(): Se llama cuando se dispara la actualización.
- onReleaseToRefresh(): Se llama cuando el usuario ha recorrido toda la distancia de pulling pero aún necesita levantar el dedo.
- onRefreshMinimized(): Se llama cuando la actualización está llevando más tiempo que el especificado en refreshMinimizeDelay.
- onConfigurationChanged(Activity activity, Configuration conf): Se llama cuando la configuración de la Activity a la que está asociada la barra cambia.
- activity: Activity a la que esta asociada la barra.
- conf: Nueva configuración.
Como
hemos visto usar esta biblioteca es muy sencillo y nos da una gran
libertad a la hora de personalizar el comportamiento de la barra de
actualización. Con esto podremos implantar el patrón Pull to
Refresh a nuestras aplicaciones.
No hay comentarios:
Publicar un comentario