miércoles, 22 de abril de 2015

Gif animado en aplicación android

Para agregar un gif animado a nuestra aplicación debemos empezar por tener el archivo .gif en la carpeta res/drawable, para este ejemplo el archivo se llama loading.gif.

Después en la carpeta res/values creamos el archivo attrs.xml con el siguiente contenido:


1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="GifView">
        <attr name="gif_source" format="reference"/>
    </declare-styleable>
</resources>

Si el archivo ya existe sólo agregue la sección declare-styleable, esto sirve para que nuestro control tenga una propiedad 'gif_source' que hará referencia al archivo .gif.

Creamos también en la carpeta src un paquete llamado com.androideazteca.controls y dentro de el una clase a la que llamaremos GifView.java con el siguiente contenido:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package com.androideazteca.controls;


import java.io.InputStream;

import com.androideazteca.animatedgif.R;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.util.AttributeSet;
import android.view.View;

public class GifView extends View {

 private InputStream gifInputStream;
 private Movie gifMovie;
 private int movieWidth, movieHeight;
 private long movieDuration;
 private long mMovieStart;

 @SuppressLint("Recycle")
 public GifView(Context context, AttributeSet attrs) {
  super(context, attrs);

  TypedArray attributes = context.obtainStyledAttributes(attrs,
    R.styleable.GifView, 0, 0);
  int src = attributes.getResourceId(R.styleable.GifView_gif_source, -1);

  gifInputStream = context.getResources().openRawResource(src);

  init(context);
 }

 private void init(Context context) {
  
  setFocusable(true);

  gifMovie = Movie.decodeStream(gifInputStream);
  movieWidth = gifMovie.width();
  movieHeight = gifMovie.height();
  movieDuration = gifMovie.duration();
 }

 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  
  setMeasuredDimension(movieWidth, movieHeight);
 }

 public int getMovieWidth() {
  
  return movieWidth;
 }

 public int getMovieHeight() {
  
  return movieHeight;
 }

 public long getMovieDuration() {
  
  return movieDuration;
 }

 @Override
 protected void onDraw(Canvas canvas) {

  long now = android.os.SystemClock.uptimeMillis();
  
  if (mMovieStart == 0) { // first time
   
   mMovieStart = now;
  }

  if (gifMovie != null) {

   int dur = gifMovie.duration();
   
   if (dur == 0) {
    
    dur = 1000;
   }

   int relTime = (int) ((now - mMovieStart) % dur);

   gifMovie.setTime(relTime);
   gifMovie.draw(canvas, 0, 0);
  
   invalidate();
  }

 }
}

Recuerden cambiar el nombre del paquete en la línea número 4:

import com.androideazteca.animatedgif.R;

Por último agregamos el siguiente contenido a la vista donde deseamos que aparezca el gif:

1
2
3
4
5
6
7
8
<com.androideazteca.controls.GifView
        xmlns:androideazteca="http://schemas.android.com/apk/res/com.androideazteca.animatedgif"
        android:id="@+id/gifviewLoading"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        androideazteca:gif_source="@drawable/loading" />

También en este fragmento es necesario cambiar el nombre del paquete en las líneas 1 y 2.

En la línea 8 se hace referencia al atributo 'gif_source' que creamos en el archivo attrs.xml, el valor es "@drawable/loading", la palabra 'loading' es el nombre del gif que está almacenado en la carpeta drawable. Para mostrar otro gif solo deben copiarlo a la carpeta drawable y cambiar el valor del atributo gif_source, poniendo el nombre del gif (sin extensión). Ejemplo:

androideazteca:gif_source="@drawable/otrogif"


Por último debemos modificar el archivo AndroidManifest.xml agregando la siguiente línea:

android:hardwareAccelerated="false"

en el activity donde usamos el control para mostrar el gif

en mi caso ha quedado así:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.androideazteca.animatedgif"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="21" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:hardwareAccelerated="false"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Pueden encontrar un código de ejemplo en esta liga:

AnimatedGif.zip


Espero que les sea de utilidad.

Saludos!

No hay comentarios.:

Publicar un comentario