Páginas

Cuenta atrás

En este post vamos a ver cómo añadir una cuenta atrás a una actividad Android. Este recurso es utilizado con frecuencia en juegos, especialmente cuando la velocidad es importante, para dar al jugador tiempo de preparase para la que se le viene encima.

En el ejemplo vamos a usar una cuenta atrás de 3 a 1, que acabará con un mensaje, y la implementación la haremos con animaciones. Lo primero que necesitaremos serán las imágenes para los números y el mensaje, como por ejemplo:



Una vez colocadas en su sitio (la correspondiente carpeta drawable), las añadiremos todas al layout de nuestra aplicación, en la posición que queramos. Por ejemplo, este código las ubica en el centro de un RelativeLayout.


1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<ImageView
        android:id="@+id/threeImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:background="@drawable/calculator_three_countdown"
        android:visibility="invisible" />
    <ImageView
        android:id="@+id/twoImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:background="@drawable/calculator_two_countdown"
        android:visibility="invisible" />
    <ImageView
        android:id="@+id/oneImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:background="@drawable/calculator_one_countdown"
        android:visibility="invisible" />
    <ImageView
        android:id="@+id/goImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:background="@drawable/calculator_go_countdown"
        android:visibility="invisible" />

Si os fijáis, las hemos marcado todas como invisibles para empezar.

Ahora pasamos al código de la actividad. Como he comentado, vamos a utilizar animaciones. La idea es presentar en orden los números de la cuenta atrás mediante una animación que los haga aparecer. Por tanto, comencemos preparando una animación para mostrar el 3.


1
2
3
4
Animation threeAnim = new ScaleAnimation(0, 1, 0, 1);
threeAnim.setDuration(1000);
findViewById(R.id.threeImage).setVisibility(View.VISIBLE);
findViewById(R.id.threeImage).startAnimation(threeAnim);

Este código deberíamos incluirlo en el método onCreate de la actividad. Lo que hace es crear un objeto ScaleAnimation, que hará crecer el tamaño de la imagen, asignarle una duracion de 1 segundo, y aplicarlo sobre la imagen, tras hacerla visible.

Con todo esto ponemos en marcha la animación. El siguiente paso sería lanzar la animación del 2, en el momento en que termine la del 3. Para esto podemos hacer uso de AnimationListener. Las animaciones Android permiten registrar oyentes, que serán notificados en el momento en que la animación comienza, acaba o se repite, mediante esta interfaz. Podemos hacer que sea directamente nuestra actividad la que implemente AnimationListener. Esto implica que tenemos que definir los siguientes métodos.


1
2
3
4
5
6
@Override
public void onAnimationStart(Animation anim) {}
@Override
public void onAnimationRepeat(Animation anim) {}
@Override
public void onAnimationEnd(Animation anim) {}

El que nos interesa ahora mismo es onAnimationEnd, al que daríamos el siguiente código.

1
2
3
4
5
6
7
8
9
if (anim == threeAnim) {
findViewById(R.id.threeImage).setVisibility(View.GONE);

twoAnim = new ScaleAnimation(0, 1, 0, 1);
twoAnim.setDuration(1000);
twoAnim.setAnimationListener(this);
findViewById(R.id.twoImage).setVisibility(View.VISIBLE);
findViewById(R.id.twoImage).startAnimation(twoAnim);
}

El parámetro anim es la animación que ha terminado; así que, si es la animación del 3, lo que tenemos que hacer es volver a ocultar su imagen, y lanzar la animación del 2.

Lógicamente, para que nuestra actividad sea notificada por las animaciones, tenemos que registrarla como oyente, como se hace en el bloque anterior con twoAnim. El bloque de lanzamiento de threeAnim en onCreate debería completarse para quedar así:

1
2
3
4
5
threeAnim = new ScaleAnimation(0, 1, 0, 1);
threeAnim.setDuration(1000);
threeAnim.setAnimationListener(this);
findViewById(R.id.threeImage).setVisibility(View.VISIBLE);
findViewById(R.id.threeImage).startAnimation(threeAnim);

Además, para poder comprobar qué animación es la que nos está notificando en cada caso, tendremos que definirlas como atributos de la clase, y no como variables locales, como hicimos en el primer bloque.


1
private Animation threeAnim, twoAnim, oneAnim, goAnim;

De esta forma cerraríamos el círculo. Sólo nos falta completar el código de onAnimationEnd para lanzar la animación del 1 al terminar la del 2, y la del mensaje al terminar la del 1. Una vez terminada la animación del mensaje todas las imágenes quedarán ocultas, y tendremos que poner en marcha el contenido real de la actividad.

Esta solución deja abiertas más opciones; por ejemplo, podemos reproducir un sonido en cada paso de la cuenta atrás, añadiendo el código correspondiente en onAnimationStart.

Podéis ver el resultado de esta implementación tanto en Human Calculator como en Fast Tap. Además, aquí os dejo el código completo.

CountdownActivity.java
activity_countdown.xml

No hay comentarios:

Publicar un comentario