El gran libro de programación avanzada con Android. José Enrique Amaro Soriano
Чтение книги онлайн.
Читать онлайн книгу El gran libro de programación avanzada con Android - José Enrique Amaro Soriano страница 7
3. ANIMACIÓN DE FOTOGRAMAS
3.1. Animación usando recursos
Una animación de fotogramas consiste en una secuencia de imágenes, cada una de las cuales se muestra en pantalla durante un tiempo determinado. La información de los fotogramas y su duración se puede incluir en un fichero xml, que colocaremos en uno de los directorios res/drawable. En el siguiente ejemplo animaremos una secuencia de seis imágenes jpg, que irán cambiando en intervalos de tres segundos. Las imágenes las copiaremos en el directorio res/drawable-mdpi. En el mismo directorio crearemos el siguiente recurso, un fichero xml con la lista de fotogramas de la animación.
Usaremos el siguiente layout, que consiste en dos botones para activar y detener la animación y un ImageView para contener las imágenes.
Finalmente, en la actividad AnimacionDeFotogramas.java declaramos la animación como un objeto de tipo AnimationDrawable. La animación comienza y se detiene ejecutando sus métodos start y stop. Para definir la animación, primero asignamos el recurso fotogramas_animados.xml al ImageView mediante setBackgroundResource y luego extraemos la animación ejecutando el método getBackground. En la figura 3.1. se muestra el resultado.
Figura 3.1. Animación de fotogramas.
Hay que advertir que el método start de AnimationDrawable no se puede ejecutar directamente en onStart para comenzar la animación automáticamente, porque la aplicación no funcionaría. También hay que controlar el tamaño de las imágenes que se usan como fotogramas. Si son muy grandes o abundantes, se puede producir un error de memoria. Por lo tanto, se debe reducir el tamaño y el número de los fotogramas tanto como sea posible.
3.2. Animación de fotogramas en Java: AnimationDrawable
En el ejemplo anterior hemos animado una serie de fotogramas. La animación se definió como un recurso, en el fichero fotogramas_animados.xml, que se asignó al background de un ImageView mediante setBackgroundResource.
La misma animación la realizaremos ahora en Java sin utilizar el recurso anterior. En Java, una animación de fotogramas es un objeto de la clase AnimationDrawable. Los fotogramas se añaden a esta animación con el método addFrame, que admite dos argumentos: la imagen a dibujar (como un objeto Drawable) y la duración del fotograma en milisegundos. El método setOneShot(boolean) controla si la animación se va a mostrar solo una vez (true) o se va a repetir (false). Para asociar la animación al background, usamos el método setBackgroundDrawable de ImageView. Este sería el programa Java de la animación, usando el layout del ejemplo anterior. El resultado es el mismo que se muestra en la figura 3.1.
3.3. Ajuste de la relación de aspecto
En los ejemplos anteriores hemos asignado una animación de fotogramas al background de un ImageView. El problema que surge en estas animaciones es que los parámetros del ImageView en el layout eran fill_parent. Esto provoca que el tamaño de las imágenes se reduzca para llenar completamente el espacio disponible, sin que se mantenga la relación altura/anchura. Si intentamos modificar el tamaño cambiando los parámetros a wrap_content en el layout, el resultado es que no se muestra nada; es decir, no se ven las imágenes. Esto se debe a que la animación es un objeto de tipo Drawable cuyas dimensiones intrínsecas son cero. No obstante, esta limitación de la clase AnimationDrawable puede solventarse parcialmente, simulando aproximadamente el efecto de wrap_content.
En primer lugar, creamos una actividad AnimacionFotoAspecto.java con el siguiente layout:
La actividad comienza creando la misma animación de fotogramas del ejemplo anterior, pero en lugar de asignarla al background, la asignaremos directamente al ImageView mediante
Esto todavía no resuelve el problema. Si intentamos iniciar la animación, veremos que la imagen no mantiene su relación de aspecto, como se observa en la figura 3.3.1. La razón es que los parámetros del ImageView son fill_parent (recordemos que no podemos usar wrap_content porque no se muestra nada). Un modo de forzar a modificar el tamaño de la imagen sería añadir márgenes mediante setPadding. Para ello tenemos que calcular el tamaño vertical que ocupa la imagen y, a partir de ahí, calcular la anchura que debería tener manteniendo su relación de aspecto.
Figura 3.3.1. Animación de fotogramas que no mantiene la relación de aspecto.
En la siguiente actividad se calcula la relación de aspecto real del primer fotograma. Seguidamente, calculamos la altura que tiene el ImageView en la pantalla mediante getMeasuredHeight. En este punto nos encontramos otro problema, ya que si escribimos estos valores en la pantalla, veremos que el ImageView tiene dimensiones nulas, como se muestra en la figura 3.3.2. La razón es que estas dimensiones se están calculando dentro del método onCreate de la actividad cuando el layout de la actividad no se ha desplegado completamente. Los contenidos solo están definidos cuando la actividad está lista para interaccionar con el usuario; por ejemplo, al pulsar uno de los botones. Por lo tanto, la solución es realizar nuestras manipulaciones dentro del método onClick. El programa Java es el siguiente:
Al calcular dentro de onClick las dimensiones del ImageView, vemos que ya no son cero, por lo que podemos calcular el margen necesario en la imagen para mantener la relación de aspecto (padding). El resultado se muestra en la figura 3.3.2. (izquierda). Hemos escrito las dimensiones del ImageView antes y después de onClick, cuando ya se ha desplegado el layout, así como la nueva anchura de la imagen y el valor necesario del padding. Es ilustrativo pulsar los botones Detener y Comenzar de nuevo, porque entonces se vuelve a calcular las dimensiones del ImageView, que se han modificado respecto al paso anterior al escribir dos líneas de texto. Esto hace recalcular la anchura de la imagen y reajustar el padding, como se observa en la figura 3.3.2. (derecha). Dicha operación puede repetirse varias veces y se verá que la relación de aspecto