Android nos permite trabajar a nivel gráfico de dos maneras, a nivel de cocina, que es con el ndk que puedes programar un mix entre java y c, para hacer gráficos de alto rendimiento, y con sdk, haciéndolo en android que hace llamadas a la cpu, depende con el nivel de gráficos que queramos trabajar.
Podemos coger una imagen y hacer una batería de imágenes, podemos definir por xml o programación este proceso.
Una misma animación se pude hacer de varias formas, podemos definir la durada de la animación, la interpolación (si el movimiento es lineal o hay un cambio), si se tiene que repetir la animación, si se tiene que reproducir al inreves, si son un conjunto animados de elementos, también podremos indicar fotogramas por segundo...
La clase ValueAnimator mantiene la pista de la animación (como por ejemplo, cuanto tiempo llevamos animando un objeto y el valor actual de la propiedad que se esta animando, esta clase encapsula TimeInterpolator, que se encarga de la interpolación de la animación y TypeEvaluator para determinar como se han de calcular los valores (enteros reales...)), con start se inicia.
Diferencia con ViewAnimation
ViewAnimation solo sirve para animar los objetos que heredan de View (ProgressBar, TextView, etc), como un canvas.
Además no expone todas las propiedades de estos objetos.
La mayoría de estas clases se encuentran en el paquete android.animation.
La clase Animator dispone de la infraestructura básica para crear animaciones, pero normalmente trabajamos con sus subclases:
Los interpoladores indican como se tienen que calcular los valores con el paso del tiempo. AccelerateDecelerateInterpolator, AccelerateInterpolator, LinearInterpolator, son ejemplos de interpoladores.
AccelerateDecelerateInterpolator
public float getInterpolation(float input){
return (float) (Math.cos((input+1)*Math.PI) /2.0f) + 0.5f;
}
LinearInterpolator
pubic float getInterpolation(float input){
return input;
}
Además no expone todas las propiedades de estos objetos.
La mayoría de estas clases se encuentran en el paquete android.animation.
La clase Animator dispone de la infraestructura básica para crear animaciones, pero normalmente trabajamos con sus subclases:
- ObjectAnimator: es una subclase de ValueAnimator que le permite establecer un objeto de destinación y la propiedad de un objeto que desea animar. Esta clase actualiza la propiedad en consecuencia cuando se calcula un nuevo valor para la animación. Podemos utilizar ObjetAnimator la mayor parte del tiempo, porque hace que el proceso de animación de los valores en objetos de destinación sean mucho mas fáciles. No obstante, hay veces que es mejor utilizar ValueAnimator directamente porque ObjetAnimator tiene mas restricciones, como la exigencia de métodos específicos accesorios en el objeto de destinación.
- AnimatorSet: Proporciona el mecanismo para hacer un grupo de animaciones juntos, para que se ejecuten el uno con el otro. Podemos configurar animaciones de objetos juntos, de manera secuencial, o después de un retraso determinado. Es decir, determinar ejes X y Y.
- ValueAnimator.
Los interpoladores indican como se tienen que calcular los valores con el paso del tiempo. AccelerateDecelerateInterpolator, AccelerateInterpolator, LinearInterpolator, son ejemplos de interpoladores.
AccelerateDecelerateInterpolator
public float getInterpolation(float input){
return (float) (Math.cos((input+1)*Math.PI) /2.0f) + 0.5f;
}
LinearInterpolator
pubic float getInterpolation(float input){
return input;
}
ms | Lineal | acc/deacc |
0 | 0 | 0 |
200 | .2 | .1 |
400 | .4 | .345 |
600 | .6 | .8 |
800 | .8 | .9 |
1000 | 1 | 1 |
Permite animar la propiedad que se le pasa como argumento.
Le ponemos set<propiedad>() y get<propietat> para obtener valores.
Si el objeto no tiene set, podemos añadirlo, podemos hacer una clase envoltorio o crear ValueAnimator. Si se especifica un solo valor, se entiende que es el final. El objeto tiene que tener un get<propiedad> para obtener el valor incial.
Le ponemos set<propiedad>() y get<propietat> para obtener valores.
Si el objeto no tiene set, podemos añadirlo, podemos hacer una clase envoltorio o crear ValueAnimator. Si se especifica un solo valor, se entiende que es el final. El objeto tiene que tener un get<propiedad> para obtener el valor incial.
Ejemplo AnimatorSet:
AnimatorSet bouncer = new AnimatorSet();
bouncer.play(bounceAnim).before(squashAnim1);
bouncer.play(squashAnim1).with(squashAnim2);
bouncer.play(squashAnim1).with(stretchAnim1);
bouncer.play(squashAnim1).with(stretchAnim2);
bouncer.play(bounceBackAnim).after(stretchAnim2);
ValueAnimator fadeAnim = ObjectAnimator.ofFloat(pilota, "alpha", 1f, 0f);
fadeAnim.setDuration(250);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(bouncer).before(fadeAnim);
animatorSet.start();
Dispondremos de un conjunto de listeners para saber que esta pasando en la animación y programar si queremos callbacks, onAnimationStart(), onAnimationEnd(), onAnimationUpdate(), onAnimationRepeat(), etc. esto nos permitirá responder por ejemplo al final de una animación (onAnimationEnd()).
ValueAnimatorAnimator fadeAnim = ObjectAnimator.ofFloat(pilota, "alpha", 1f, 0f);
fadeAnim.setDuration(250);
fadeAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
pilotes.remove(((ObjectAnimator)animation).getTarget());
}
}fadeAnim.setDuration(250);
fadeAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
pilotes.remove(((ObjectAnimator)animation).getTarget());
}
La animación por llaves consiste en especificar llaves formadas por tiempo/valor. Cada valor tiene su propio interpolador para controlar el comportamiento de la animación en el intervalo definido.
Se hacen servir métodos ofFloat(), etc.
Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);
Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
PropertyValuesHolder rotacio = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
ObjectAnimator animacio = ObjectAnimator.ofPropertyValuesHolder(target, rotacio)
animacio.setDuration (5000ms);
Los objetos heredan de View (prácticamente todos los estudiados) disponen de propiedades translationX, translationY, rotation, rotationX, rotationY, alpha, etc... para ser manipulados con mayor facilidad. Por ejemplo:
ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f);
La clase ViewPropertyAnimator permite animar varias propiedades en paralelo, hay tres maneras de hacer lo mismo:
Con ObjetcAnimator:
ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f);
ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f);
AnimatorSet animSetXY = new AnimatorSet();
animSetXY.playTogether(animX, animY);
animSetXY.start();
Con PropertyValuesHolder:
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x",50f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start();
Con ViewPropertyAnimator (los hace de forma simultanea):
myView.animate().x(50f).y(100f);
También podemos poner las animaciones en un XML en res/anim/, por ejemplo:
animacion.xml
<set android:ordering="sequentially"><set>
<objectAnimator
android:propertyName="x"
android:duration="500"
android:valueTo="400"
android:valueType="intType"/>
<objectAnimator
android:propertyName="y"
android:duration="500"
android:valueTo="300"
android:valueType="intType"/>
</set>
<objectAnimator
android:propertyName="alpha"
android:duration="500"
android:valueTo="1f"/>
</set>
En el programa tendremos que poner:
AnimatorSet set = (AnimatorSet)
AnimatorInflater.loadAnimator(myContext,R.anim.animacion);
set.setTarget(myObject);
set.start();
Animaciones de vistas
Se puede utilizar el sistema de animaciones de vistas para realizar animaciones interpoladas de controles de vista.Una animación de interpolación puede realizar una serie de transformaciones simples (posición, medida, rotación y transparencia) en el contenido de un objeto View. Por lo tanto, si por ejemplo tenemos un objeto TextView, se puede mover, girar, crecer o reducir la medida del texto. Si se tiene una imagen de fondo, la imagen de fondo será transformada juntamente con el texto. El paquete animation ofrece todas las clases que se utilizan en una animación de interpolación.
Una secuencia de instrucciones de animación define la animación de interpolación, definida por cualquier XML o código Java. Igual que con la definición de un diseño, se recomienda un archivo XML porque es mas facil de leer, reutilizable...
Las instrucciones de animaciones definen las transformaciones que se desean producir, cuando van a ocurrir y cuanto tiempo tienen que adoptar para la aplicación. Las transformacioens pueden ser secuenciales o simultanias, por ejemplo, puede hacer que el contenido de un TextView se mueva de izquierda a derecha y después girar 180 grados, o hacerlo de forma simultanea.
Cada transformación necesita un conjunto de parámetros específicos para esta transformación (medida inicial, angulo inicial, final del angulo, final de la medida final, etc.), y también un conjunto de parámetros comunes (por ejemplo, hora de inicio y de paro). Para hacer varias transformaciones que se sucedan simultaneamente, se les da la misma hora de inicio, pero para que sean secuenciales, hace falta calcular el tiempo de inicio más la durada de la transformación anterior.
El archivo de animación XML pertenece al res/anim/ directorio del projecto Android.
El archivo tiene que tener un elemento raiz, será único: <alpha>,<scale>,<translate>,<rotate>, elemento interpolador o <set>, elemento que tiene grupos de elementos (que pueden incluir otro <set>). Por defecto, todas las instrucciones de animaciones se aplican simultaneamente. Para hacerlos se producen de forma secuencial, se tiene que especificar el startOffset atributo.
Por ejemplo:
set android:shareInterpolator="false">
<scale
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromXScale="1.0"
android:toXScale="1.4"
android:fromYScale="1.0"
android:toYScale="0.6"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="false"
android:duration="700" />
<set android:interpolator="@android:anim/decelerate_interpolator">
<scale
android:fromXScale="1.4"
android:toXScale="0.0"
android:fromYScale="0.6"
android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="700"
android:duration="400"
android:fillBefore="false" />
<rotate
android:fromDegrees="0"
android:toDegrees="-45"
android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="700"
android:duration="400" />
</set>
</set>
Con este XML guardado como salto.xml en res/anim del directorio del proyecto, el siguiente código hará referencia a él y aplicará a una ImageView el objeto de la disposición.
ImageView imatge = (ImageView) findViewById (R.id.imatge);
Animation a = AnimationUtils.loadAnimation (això, R.anim.salt);
imatge.startAnimation (a);
Animaciones de recursos draw
Android permite cargar una serie de recursos Drawable uno tras otro, para crear una animación. Esta es una animación tradicional en el sentido que se crea con una secuencia de imagenes diferentes, como el rollo de una película. La clase AnimationDrawable es la base para las animaciones Drawable.El archivo XML de este tipo de animaciones pertenece al directorio res/drawable/ del proyecto de android. En este caso, las instrucciones estan en orden y la duración para cada cuadro de animación.
El archivo XML consiste en un elemento <animation-list> como el nodo raiz y la serie de nodos hijos <item> que definen cada uno un marco: un recurso dibujable para el marco y la durada para cada frame.
fondo.xml
<animation-listxmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<item
android:drawable="@drawable/rocket_thrust1"
android:duration="200" />
<item
android:drawable="@drawable/rocket_thrust2"
android:duration="200" />
<item
android:drawable="@drawable/rocket_thrust3"
android:duration="200" />
</animation-list>
Código:
AnimationDrawable a;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ImageView imatge = (ImageView) findViewById(R.id.imatge);
imatge.setBackgroundResource(R.drawable.fons);
a = (AnimationDrawable) imatge.getBackground();
}
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
a.start();
return true;
}
return super.onTouchEvent(event);
}
4. Desarrolla una aplicación que muestre una animación en forma de secuencia repetitiva en la que un texto siga una forma de recuadro. Hazlo con programación Java y con código XML.
5. Crea una animación de una imagen que va rebotando dentro de un contenedor.
Soluciones (Cambiar el android manifest para las diferentes actividades).
Para mas detalles, consultad Android developers.