Ejecutar Gif animado en Android

By | 6 enero 2014

Resulta extraño que a Google no se le haya ocurrido pensar en incorporar un componente nativo en Android para poder ver un Gif animado, pero por muy extraño parezca así es.

No pasa nada, y aunque no hay mucha documentación al respecto, indagando por la red he conseguido completar una clase que de forma muy simple ejecuta el Gif animado como querriamos que lo hiciera un componente nativo.

Aquí tenemos la clase que realiza la tarea.

package com.pjcom.view;

import java.io.InputStream;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;

/**
 * @author Daniel Pardo Ligorred @ www.yizztech.com Based ON (Sergei)
 *         http://weavora.com/blog/2012/02/07/android-how-to-use-animated-gif/
 */
public class GifView extends ImageView {

	private Context context;
	private Double scaleX, scaleY;
	private Movie movie;
	private long moviestart;

	public GifView(Context context) {

		super(context);
		this.context = context;
	}

	public GifView(Context context, AttributeSet attrs) {

		super(context, attrs);
		this.context = context;
	}

	public GifView(Context context, AttributeSet attrs, int defStyle) {

		super(context, attrs, defStyle);
		this.context = context;
	}

	public void loadGIFResource(int id) {

		InputStream is = this.context.getResources().openRawResource(id);

		this.movie = Movie.decodeStream(is);
	}

	@Override
	protected void onDraw(Canvas canvas) {

		this.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

		super.onDraw(canvas);

		long currentTime = android.os.SystemClock.uptimeMillis();

		if (this.moviestart == 0) {

			this.scaleX = (double) this.getWidth()
					/ (double) this.movie.width();
			this.scaleY = (double) this.getHeight()
					/ (double) this.movie.height();

			this.moviestart = currentTime;
		}

		if (movie != null) {

			this.movie
					.setTime((int) ((currentTime - this.moviestart) % this.movie
							.duration()));

			canvas.scale(this.scaleX.floatValue(), this.scaleY.floatValue());
			this.movie.draw(canvas, this.scaleX.floatValue(),
					this.scaleY.floatValue());
		}

		this.invalidate();
	}
}

Como podéis ver la clase extiende de ImageView, posee un método loadGIFResource(int id) donde le tenemos que pasar el id de nuestro gif, y en el método onDraw(Canvas canvas) realiza la labor de ejecución de la Movie donde hemos almacenado el gif y lo escala al tamaño de nuestra view, tambien hace alguna otra cosa interesante, como cancelar la aceleración 3D por Hardware, ya que sino en algunos móviles no se ve el Gif.

Todo lo que hay que hacer es especificar en nuestro layout el componente.

<com.pjcom.view.GifView
        android:id="@+id/dialog_loading"
        android:layout_width="@dimen/dialog_loading_width"
        android:layout_height="@dimen/dialog_loading_height"
        android:layout_gravity="center_vertical" />

Y en nuestra activity especificarle el id del recurso.

GifView gifView = (GifView) findViewById(R.id.myGif);

gifView.loadGIFResource(R.drawable.myGif);
Comparte esta entrada enShare on LinkedIn0Tweet about this on Twitter0Share on Facebook0Share on Google+0

3 thoughts on “Ejecutar Gif animado en Android

  1. Juan Pablo

    Obtengo un NullPointerException cuando sigo los pasos que dices en el preview que provee el ADT. Esto es normal?

  2. Iván

    Un gran aporte.
    Una duda, al seguir tus instrucciones me marca un error:
    java.lang.NullPointerException at ivanhdzd.trainerbeginners.GifView.VerGif.onDraw(VerGif.java:47)
    Checando la línea el error esta en:
    this.scaleX = (double) this.getWidth()
    / (double) this.movie.width();
    this.scaleY = (double) this.getHeight()
    / (double) this.movie.height();
    Cómo puedo revolverlo?

  3. Daniel Post author

    Os respondo a los dos, esta implementación no funciona bien en las versiones mas recientes de Android, por eso no es nada recomendable utilizarla en producción, el mejor recurso para ejecutar un gif en Android es hacer uso de un AnimationDrawable, supone tener que descomponer el gif animado en sus respectivas imagenes para poder referenciarlas en el animation-list, pero es la mejor opción posible ahora mismo que provee el SDK.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *