Tip Android #12: animar mostrar/ocultar layout con desplazamientos

02/03/2013
android tip

En este tip vamos a ver un ejemplo muy simple de animación para desplazar layouts y que se aplicará a una acción habitual como es mostrar/ocultar un layout. Las animaciones de Android tienen mucho más que ofrecernos y además fueron mejoradas en Honeycomb para hacer más fácil su uso e incluso poder modificar las propiedades de los objetos animados. Estas nuevas características se pueden usar en cualquier versión de Android ya que están incluídas en la librería de compatibilidad, aunque lo más práctico es utilizar NineOldAndroids, otra de las magníficas librerías Open Source creadas por Jake Wharton como ActionBarSherlock

El layout de ejemplo es el siguiente:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <LinearLayout
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/buttonMostrar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="mostrar"
            android:text="@string/mostrar" />

        <Button
            android:id="@+id/buttonOcultar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="ocultar"
            android:text="@string/ocultar" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/animado"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@android:color/darker_gray"
        android:gravity="center"
        android:visibility="gone" >

        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/texto"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:textColor="@android:color/black" />
    </LinearLayout>

</LinearLayout>

Y la Activity

package com.danielme.tipsandroid.animacion;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.LayoutAnimationController;
import android.view.animation.TranslateAnimation;
import android.widget.LinearLayout;

import com.danieme.tipsandroid.animacion.R;

public class MainActivity extends Activity
{

	private LinearLayout layoutAnimado;

	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		layoutAnimado = (LinearLayout) findViewById(R.id.animado);
	}

	public void mostrar(View button)
	{
		if (layoutAnimado.getVisibility() == View.GONE)
		{
			animar(true);
			layoutAnimado.setVisibility(View.VISIBLE);
		}
	}

	public void ocultar(View button)
	{
		if (layoutAnimado.getVisibility() == View.VISIBLE)
		{
			animar(false);
			layoutAnimado.setVisibility(View.GONE);
		}

	}
	
	private void animar(boolean mostrar)
	{
		AnimationSet set = new AnimationSet(true);
		Animation animation = null;
		if (mostrar)
		{
			//desde la esquina inferior derecha a la superior izquierda
			animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 1.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 1.0f, Animation.RELATIVE_TO_SELF, 0.0f);
		}
		else
		{    //desde la esquina superior izquierda a la esquina inferior derecha
			 animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 1.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 1.0f);
		}
                //duración en milisegundos
		animation.setDuration(500);
		set.addAnimation(animation);
		LayoutAnimationController controller = new LayoutAnimationController(set, 0.25f);

		layoutAnimado.setLayoutAnimation(controller);
		layoutAnimado.startAnimation(animation);
	}

}

El código es claro y simple, ejecuta primero la animación con la traslación deseada y luego muestra u oculta el layout. Se basa en el uso de TranslateAnimation y en el constructor se indica la posición de inicio y fin de la animación, primero en horizontal y luego en vertical, medida en porcentaje (un float entre 0 y 1). En nuestro caso la traslación es completa, siendo este el resultado:

Las animaciones también se pueden definir en xml, de hecho probablemente sea más práctico tenerlas todas definidas en el directorio correspondiente. Para nuestro ejemplo, podemos crear el fichero mostrar.xml en /res/anim con el siguiente contenido:

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false" >

    <translate
        android:duration="500"
        android:fromXDelta="100%"
        android:toXDelta="0%"
        android:fromYDelta="100%"        
        android:toYDelta="0%" />

</set>

y ocultar.xml

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false" >

    <translate
        android:duration="500"
        android:fromXDelta="0%"
        android:toXDelta="100%"
        android:fromYDelta="0%"        
        android:toYDelta="100%" />

</set>

Se ejecutaría con el siguiente código:

Animation animation=AnimationUtils.loadAnimation(this, R.anim.mostrar);
layoutAnimado.startAnimation(animation);

El proyecto completo para Eclipse ADT se encuentra en Github. Para más información sobre cómo utilizar GitHub, consultar este artículo.

<< TIPS ANDROID

5 Responses to Tip Android #12: animar mostrar/ocultar layout con desplazamientos

  1. I truly appreciate this post. I have been looking all over for this! Thank goodness I found it on Bing. You have made my day! Thank you again

  2. camilo leon dice:

    muchas gracias

  3. Akagami dice:

    mera pija! muchas gracias😀

  4. Miller dice:

    Y si solo es para mostrar la mitad de un layout?

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: