Android ens permet treballar a nivell gràfic de dues maneres: a nivell de cuina, que és amb el NDK on pots programar un mix entre Java i C per fer gràfics d'alt rendiment, i amb SDK, fent-ho en Android que fa cridades a la CPU, depenent del nivell de gràfics amb què vulguem treballar.

Podem agafar una imatge i fer una bateria d'imatges, podem definir per XML o programació aquest procés.

Una mateixa animació es pot fer de diverses formes: podem definir la duració de l'animació, la interpolació (si el moviment és lineal o hi ha un canvi), si s'ha de repetir l'animació, si s'ha de reproduir al revés, si són un conjunt animat d'elements, també podrem indicar fotogrames per segon...

La classe ValueAnimator manté el seguiment de l'animació (com per exemple, quant de temps portem animant un objecte i el valor actual de la propietat que s'està animant; aquesta classe encapsula TimeInterpolator, que s'encarrega de la interpolació de l'animació, i TypeEvaluator per determinar com s'han de calcular els valors (enters, reals...)), amb start s'inicia.

*

Diferència amb ViewAnimation

ViewAnimation només serveix per animar els objectes que hereten de View (ProgressBar, TextView, etc.), com un canvas.

A més, no exposa totes les propietats d'aquests objectes.

La majoria d'aquestes classes es troben al paquet android.animation.

La classe Animator disposa de la infraestructura bàsica per crear animacions, però normalment treballem amb les seves subclasses:

  • ObjectAnimator: és una subclasse de ValueAnimator que li permet establir un objecte de destinació i la propietat d'un objecte que vol animar. Aquesta classe actualitza la propietat en conseqüència quan es calcula un nou valor per a l'animació. Podem utilitzar ObjectAnimator la major part del temps, perquè fa que el procés d'animació dels valors en objectes de destinació sigui molt més fàcil. No obstant això, hi ha vegades que és millor utilitzar ValueAnimator directament perquè ObjectAnimator té més restriccions, com l'exigència de mètodes específics accessoris en l'objecte de destinació.
  • AnimatorSet: Proporciona el mecanisme per fer un grup d'animacions juntes, perquè s'executin l'una amb l'altra. Podem configurar animacions d'objectes juntes, de manera seqüencial, o després d'un retard determinat. És a dir, determinar eixos X i Y.
  • ValueAnimator.

Els avaluadors diuen com s'han de calcular els valors de les propietats que s'estan animant. Disposen d'IntEvaluator per a les propietats int, FloatEvaluator per a propietats float, ArgbEvaluator per a propietats de color i TypeEvaluator que és una interfície.

Els interpoladors indiquen com s'han de calcular els valors amb el pas del temps. AccelerateDecelerateInterpolator, AccelerateInterpolator, LinearInterpolator, són exemples d'interpoladors.

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;

}

msLinealacc/deacc
000
200.2.1
400.4.345
600.6.8
800.8.9
100011

Permet animar la propietat que se li passa com a argument.

Li posem set<propietat>() i get<propietat> per obtenir valors.

Si l'objecte no té set, podem afegir-ho, podem fer una classe embolcall o crear ValueAnimator. Si s'especifica un sol valor, s'entén que és el final. L'objecte ha de tenir un get<propietat> per obtenir el valor inicial.

Exemple 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();*

Disposarem d'un conjunt de listeners per saber què està passant en l'animació i programar si volem callbacks, onAnimationStart(), onAnimationEnd(), onAnimationUpdate(), onAnimationRepeat(), etc. Això ens permetrà respondre per exemple al final d'una animació (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()); }}

L'animació per fotogrames clau (keyframes) consisteix a especificar claus formades per temps/valor. Cada valor té el seu propi interpolador per controlar el comportament de l'animació en l'interval definit.

Es fan servir mètodes 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);

Els objectes que hereten de View (pràcticament tots els estudiats) disposen de propietats translationX, translationY, rotation, rotationX, rotationY, alpha, etc... per ser manipulats amb més facilitat. Por exemple:

ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f);

La classe ViewPropertyAnimator permet animar diverses propietats en paral·lel, hi ha tres maneres de fer el mateix:

Amb ObjectAnimator:

ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f); ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f); AnimatorSet animSetXY = new AnimatorSet(); animSetXY.playTogether(animX, animY); animSetXY.start();Amb PropertyValuesHolder:

PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x",50f); PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f); ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start();

Amb ViewPropertyAnimator (els fa de forma simultània):

myView.animate().x(50f).y(100f);

També podem posar les animacions en un XML a res/anim/, per exemple:

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>*

Al programa haurem de posar:

AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext,R.anim.animacion); set.setTarget(myObject); set.start();

Animacions de vistes

Es pot utilitzar el sistema d'animacions de vistes per realitzar animacions interpolades de controls de vista.

Una animació d'interpolació pot realitzar una sèrie de transformacions simples (posició, mida, rotació i transparència) en el contingut d'un objecte View. Per tant, si per exemple tenim un objecte TextView, es pot moure, girar, créixer o reduir la mida del text. Si es té una imatge de fons, la imatge de fons serà transformada conjuntament amb el text. El paquet animation ofereix totes les classes que s'utilitzen en una animació d'interpolació.

Una seqüència d'instruccions d'animació defineix l'animació d'interpolació, definida per qualsevol XML o codi Java. Igual que amb la definició d'un disseny, es recomana un fitxer XML perquè és més fàcil de llegir, reutilitzable...

Les instruccions d'animacions defineixen les transformacions que es volen produir, quan han d'ocórrer i quant de temps han d'adoptar per a l'aplicació. Les transformacions poden ser seqüencials o simultànies, per exemple, pot fer que el contingut d'un TextView es mogui d'esquerra a dreta i després girar 180 graus, o fer-ho de forma simultània.

Cada transformació necessita un conjunt de paràmetres específics per a aquesta transformació (mida inicial, angle inicial, final de l'angle, final de la mida final, etc.), i també un conjunt de paràmetres comuns (per exemple, hora d'inici i d'aturada). Per fer diverses transformacions que se succeeixin simultàniament, se'ls dóna la mateixa hora d'inici, però perquè siguin seqüencials, cal calcular el temps d'inici més la duració de la transformació anterior.

El fitxer d'animació XML pertany al directori res/anim/ del projecte Android.

El fitxer ha de tenir un element arrel, que serà únic: <alpha>,<scale>,<translate>,<rotate>, element interpolador o <set>, element que té grups d'elements (que poden incloure un altre <set>). Per defecte, totes les instruccions d'animacions s'apliquen simultàniament. Per fer que es produeixin de forma seqüencial, s'ha d'especificar l'atribut startOffset.

Per exemple:

*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>*

Amb aquest XML desat com a salto.xml a res/anim del directori del projecte, el següent codi hi farà referència i aplicarà a una ImageView l'objecte de la disposició.

ImageView imatge = (ImageView) findViewById (R.id.imatge); Animation a = AnimationUtils.loadAnimation (això, R.anim.salt); imatge.startAnimation (a);

Animacions de recursos drawable

Android permet carregar una sèrie de recursos Drawable un rere l'altre, per crear una animació. Aquesta és una animació tradicional en el sentit que es crea amb una seqüència d'imatges diferents, com el rotlle d'una pel·lícula. La classe AnimationDrawable és la base per a les animacions Drawable.

El fitxer XML d'aquest tipus d'animacions pertany al directori res/drawable/ del projecte d'Android. En aquest cas, les instruccions estan en ordre i la duració per a cada quadre d'animació.

El fitxer XML consisteix en un element <animation-list> com el node arrel i la sèrie de nodes fills <item> que defineixen cadascun un marc: un recurs dibuixable per al marc i la duració per a cada frame.

fondo.xml

<animation-list
xmlns: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>

Codi:

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); }

  1. Desenvolupa una aplicació que mostri una animació en forma de seqüència repetitiva en què un text segueixi una forma de requadre. Fes-ho amb programació Java i amb codi XML.
  1. Crea una animació d'una imatge que va rebotant dins d'un contenidor.

Solucions (Canviar l'android manifest per a les diferents activitats).

PDF

Per a més detalls, consulteu Android developers.