Desarrollo en Android T06 - Animaciones en Android con Android Studio
En Android es posible definir animaciones de Rotación, Traslación y Escala utilizando las librerías predefinidas RotateAnimation, TranslateAnimation y RotateAnimation, incluidas en la API de desarrollo.
Adicional a estas librerías se utiliza la librería AnimationUtils, que permite controlar la duración de las animaciones.
import android.view.animation.AnimationUtils;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
Para definir las animaciones se crea un nuevo recurso de animación donde se establecen los parámetros que tendrá.
1.- Para iniciar, en Android Studio se hace clic derecho sobre la carpeta res (Recursos) y posteriormente en New + Android resource file, con esto se creará la carpeta anim donde se almacenarán los recursos de animación.
Nota: Si la carpeta anim ya existe se hace clic en ella y en New + Animation resource file.
2.- El cuadro de dialogo New Resourse File permite crear el archivo XML donde se configurará la animación, los parámetros iniciales son los siguientes:
File name : Nombre de la animación.
Resource type: Animation (para crear los nuevos recursos dentro de la carpeta anim).
Root element: tipo de animación que se desea crear.
Source set: paquete principal
Directory name: Carpeta donde se guardarán los recursos.
3.- El resultado de crear el recurso es el siguiente, un archivo de nombre rotate_animation1.xml con el siguiente contenido.
xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android">
</rotate>
<rotate xmlns:android="http://schemas.android.com/apk/res/android">
</rotate>
4.- Para Rotación se creará el código siguiente con los siguientes parámetros:
duration : duración en milesimas de segundo, 1000 equivale a un segundo.
fillAfter : al finalizar la animación esta conserva su estado, de otra forma regresa a su valor original.
fromDegrees: posición inicial del Widget, el valor es en radianes.
toDegrees: posición final del Widget, el valor es en radianes.
pivotX: pivote en X que se toma como referencia para la animación.
pivotY: pivote en Y que se toma como referencia para la animación.
xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:fillAfter="true"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="-90" />
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:fillAfter="true"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="-90" />
5.- Para Traslación se siguen los mismos pasos desde el punto 1, y se toman como referencia los siguientes parámetros:
fromXDelta : punto en X inicial para la animación.
toXDelta: punto en X final para la animación.
formYDelta: punto en Y inicial para la animación.
toYDelta: punto en Y final para la animación.
En este ejemplo como se dan valores en X e Y la animación será un desplazamiento en diagonal hasta llegar a los punto de X e Y finales.
xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:fillAfter="true"
android:fromXDelta="0"
android:toXDelta ="200"
android:fromYDelta ="0"
android:toYDelta = "200"/>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:fillAfter="true"
android:fromXDelta="0"
android:toXDelta ="200"
android:fromYDelta ="0"
android:toYDelta = "200"/>
6.- Para Escala se siguen los mismos pasos desde el punto 1, y se toman como referencia los siguientes parámetros:
fromXScale: valor inicial en X para la escala.
toXScale : valor final en X para la escala.
fromYScale : valor inicial en Y para la escala.
toYScale: valor final en Y para la escala.
Si el valor en toXScale es mayor al valor fromXScale, el resultado sera que el Widget se haga más grande, y si es al contrario el Widget se hará pequeño.
xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:fillAfter="true"
android:fromXScale="0"
android:toXScale="2"
android:fromYScale ="0"
android:toYScale ="2"
android:pivotX="50%"
android:pivotY="50%"/>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:fillAfter="true"
android:fromXScale="0"
android:toXScale="2"
android:fromYScale ="0"
android:toYScale ="2"
android:pivotX="50%"
android:pivotY="50%"/>
7.- Es importante conocer el punto donde se estable el pivote, ya que dependiendo de su ubicación las animaciones tendrán un efecto diferente.
En el caso de la rotación pude girar alrededor de un punto interior o exterior, e inclusive dentro de su centro.
En la traslación el pivote también determina la nueva posición.
En el escalado se aprecia la diferencia más claramente
8. Para complementar el ejemplo se crea un layout con 3 componentes, a los que se les aplicarán las animaciones.
TextView1 - Player 1
TextView2 - Player 2
Button - Play
xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="mx.blogspot.salvadorhm.animations.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView1"
android:text="@string/player1"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginRight="85dp"
android:layout_marginEnd="85dp"
android:layout_marginTop="97dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/player2"
android:id="@+id/textView2"
android:layout_marginLeft="42dp"
android:layout_marginStart="42dp"
android:layout_alignTop="@+id/textView1"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/buttonText"
android:id="@+id/button"
android:layout_below="@+id/textView1"
android:layout_centerHorizontal="true"
android:layout_marginTop="51dp" />
</RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="mx.blogspot.salvadorhm.animations.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView1"
android:text="@string/player1"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginRight="85dp"
android:layout_marginEnd="85dp"
android:layout_marginTop="97dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/player2"
android:id="@+id/textView2"
android:layout_marginLeft="42dp"
android:layout_marginStart="42dp"
android:layout_alignTop="@+id/textView1"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/buttonText"
android:id="@+id/button"
android:layout_below="@+id/textView1"
android:layout_centerHorizontal="true"
android:layout_marginTop="51dp" />
</RelativeLayout>
9. - En el archivo MainActivity se crean los 3 componentes que se utilizarán:
TextView textView1;
TextView textView2;
Button button;
TextView textView2;
Button button;
10. Con un Cast y el método findViewById se vinculan los componentes creados con la interfaz gráfica definida en el archivo XML.
textView1 = (TextView) findViewById(R.id.textView1);
textView2 = (TextView) findViewById(R.id.textView2);
button = (Button)findViewById(R.id.button);
button = (Button)findViewById(R.id.button);
11. - A continuación se crea un objeto para cada animación:
RotateAnimation para las animaciones de rotacón.
TranslateAnimation para las animaciones de movimiento.
ScaleAnimation para las animaciones de escala.
Cada uno de estos objetos se cargan con la animación definida en los xml creados en el punto 4.
RotateAnimation rotate = (RotateAnimation) AnimationUtils.loadAnimation(this, R.anim.rotate_animation);
TranslateAnimation translate = (TranslateAnimation) AnimationUtils.loadAnimation(this, R.anim.translate_animation);
ScaleAnimation scale = (ScaleAnimation)AnimationUtils.loadAnimation(this, R.anim.scale_animation);
12. - Por último se asina la animación a cada uno de los widgets de la interfaz, de forma que cada uno tenga una animación diferente.
textView1.setAnimation(rotate);
textView2.setAnimation(translate);
button.setAnimation(scale);
textView2.setAnimation(translate);
button.setAnimation(scale);
13. - El ejercicio queda como se muestra a continuación
public class MainActivity extends AppCompatActivity {
TextView textView1;
TextView textView2;
Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView1 = (TextView) findViewById(R.id.textView1);
textView2 = (TextView) findViewById(R.id.textView2);
button = (Button)findViewById(R.id.button);
RotateAnimation rotate = (RotateAnimation) AnimationUtils.loadAnimation(this, R.anim.rotate_animation);
TranslateAnimation translate = (TranslateAnimation) AnimationUtils.loadAnimation(this, R.anim.translate_animation);
ScaleAnimation scale = (ScaleAnimation)AnimationUtils.loadAnimation(this, R.anim.scale_animation);
textView1.setAnimation(rotate);
textView2.setAnimation(translate);
button.setAnimation(scale);
}
}
TextView textView1;
TextView textView2;
Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView1 = (TextView) findViewById(R.id.textView1);
textView2 = (TextView) findViewById(R.id.textView2);
button = (Button)findViewById(R.id.button);
RotateAnimation rotate = (RotateAnimation) AnimationUtils.loadAnimation(this, R.anim.rotate_animation);
TranslateAnimation translate = (TranslateAnimation) AnimationUtils.loadAnimation(this, R.anim.translate_animation);
ScaleAnimation scale = (ScaleAnimation)AnimationUtils.loadAnimation(this, R.anim.scale_animation);
textView1.setAnimation(rotate);
textView2.setAnimation(translate);
button.setAnimation(scale);
}
}
14. - Resultado final
Inicio de la animación
Fin de la animación
Comentarios