20

My layout have lots of imageviews. I want to show .gif animated file in just one imageview. I tried Yash method (Adding gif image in an ImageView in android) but .gif file shown all layout. Other views dissappeared.

I want to show all.

Any idea?

Community
  • 1
  • 1
Breed Hansen
  • 1,159
  • 5
  • 13
  • 21
  • Show us some code, a better description of how it should look (which we may be able to grasp by looking at your xml layout) and a screen cap of how it fails. – MarsAtomic May 10 '13 at 09:44
  • I got solution, refer to this link. http://stackoverflow.com/questions/3660209/display-animated-gif/23670399#23670399 – nirav kalola May 15 '14 at 06:16
  • Possible duplicate of [Adding gif image in an ImageView in android](http://stackoverflow.com/questions/6533942/adding-gif-image-in-an-imageview-in-android) – msangel Feb 25 '17 at 02:54

8 Answers8

17

If you don't want to use Glide, just add this to your dependencies and create your unique 'gif'. Check for the latest version before use. ImageView:

implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.19'

Works very efficiently with minimal lines of code. An example is:

<pl.droidsonroids.gif.GifImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/dancer"
        android:src="@drawable/maddancer" />
Pradeesh tet
  • 617
  • 7
  • 16
Taslim Oseni
  • 6,086
  • 10
  • 44
  • 69
10

With Third Party Dependency.

Add following dependency to your app gradle file

dependencies {
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.17'

}

Then after sync your project. When synchronization is done, go to your layout file and add the following code

<pl.droidsonroids.gif.GifImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/gif_file"/>

This is simplest way to display .gif images into imageview you can deal with as normal android ImageView Reference from this answer

Another way to display .gif into imageview without adding any dependency into app gradle file.

Put your .gif file into res/raw folder, in your fragment or activity and than you can set gif in imageview like

GifAnimationDrawable gif;
    
    try {
            gif = new 
             GifAnimationDrawable(getResources().openRawResource(R.raw.download));
            gif.setOneShot(false);
        } catch (NotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        ivGif.setImageDrawable(gif);
        gif.setVisible(true, true);
    }

1)GifAnimationDrawable .java

public class GifAnimationDrawable extends AnimationDrawable

    {
        private boolean decoded;
    
    private GifDecoder mGifDecoder;

    private Bitmap mTmpBitmap;

    private int height, width;
    
    public GifAnimationDrawable(File f) throws IOException
    {
        this(f, false);
    }
    
    public GifAnimationDrawable(InputStream is) throws IOException
    {
        this(is, false);
    }
    
    public GifAnimationDrawable(File f, boolean inline) throws IOException
    {
        this(new BufferedInputStream(new FileInputStream(f), 32768), inline);
    }
    
    public GifAnimationDrawable(InputStream is, boolean inline) throws IOException
    {
        super();
        InputStream bis = is;
        if(!BufferedInputStream.class.isInstance(bis)) bis = new BufferedInputStream(is, 32768);
        decoded = false;
        mGifDecoder = new GifDecoder();
        mGifDecoder.read(bis);
        mTmpBitmap = mGifDecoder.getFrame(0);
        android.util.Log.v("GifAnimationDrawable", "===>Lead frame: ["+width+"x"+height+"; "+mGifDecoder.getDelay(0)+";"+mGifDecoder.getLoopCount()+"]");
        height = mTmpBitmap.getHeight();
        width = mTmpBitmap.getWidth();
        addFrame(new BitmapDrawable(mTmpBitmap), mGifDecoder.getDelay(0));
        setOneShot(mGifDecoder.getLoopCount() != 0);
        setVisible(true, true);
        if(inline){
            loader.run();
        }else{
            new Thread(loader).start();
        }
    }
    
    public boolean isDecoded(){ return decoded; }
    
    private Runnable loader = new Runnable(){
        public void run() 
        {
            mGifDecoder.complete();
            int i, n = mGifDecoder.getFrameCount(), t;
            for(i=1;i<n;i++){
                mTmpBitmap = mGifDecoder.getFrame(i);
                t = mGifDecoder.getDelay(i);
                android.util.Log.v("GifAnimationDrawable", "===>Frame "+i+": "+t+"]");
                addFrame(new BitmapDrawable(mTmpBitmap), t);
            }
            decoded = true;
            mGifDecoder = null;
        }
    };
    
    public int getMinimumHeight(){ return height; }
    public int getMinimumWidth(){ return width; }
    public int getIntrinsicHeight(){ return height; }
    public int getIntrinsicWidth(){ return width; }
}
  1. GifDecoder.java

    public class GifDecoder

    {

     public static final int STATUS_OK = 0;  
     public static final int STATUS_FORMAT_ERROR = 1;
     public static final int STATUS_OPEN_ERROR = 2;  
     protected static final int MAX_STACK_SIZE = 4096;
     public static final    int MIN_DELAY                   = 100;
     public static final    int MIN_DELAY_ENFORCE_THRESHOLD = 20;
     protected InputStream in;
     protected int status;
     protected int width; // full image width
     protected int height; // full image height
     protected boolean gctFlag; // global color table used
     protected int gctSize; // size of global color table
     protected int loopCount = 1; // iterations; 0 = repeat forever
     protected int[] gct; // global color table
     protected int[] lct; // local color table
     protected int[] act; // active color table
     protected int bgIndex; // background color index
     protected int bgColor; // background color
     protected int lastBgColor; // previous bg color
     protected int pixelAspect; // pixel aspect ratio
     protected boolean lctFlag; // local color table flag
     protected boolean interlace; // interlace flag
     protected int lctSize; // local color table size
     protected int ix, iy, iw, ih; // current image rectangle
     protected int lrx, lry, lrw, lrh;
     protected Bitmap image; // current frame
     protected Bitmap lastBitmap; // previous frame
     protected byte[] block = new byte[256]; // current data block
     protected int blockSize = 0; // block size last graphic control extension info
     protected int dispose = 0; // 0=no action; 1=leave in place; 2=restore to bg; 3=restore to prev
     protected int lastDispose = 0;
     protected boolean transparency = false; // use transparent color
     protected int delay = 0; // delay in milliseconds
     protected int transIndex; // transparent color index
     // LZW decoder working arrays
     protected short[] prefix;
     protected byte[] suffix;
     protected byte[] pixelStack;
     protected byte[] pixels;
     protected Vector<GifFrame> frames; // frames read from current file
     protected int frameCount;
    
     private boolean readComplete;
    
     public GifDecoder()
     {
         readComplete = false;
     }
    
     private static class GifFrame {
         public GifFrame(Bitmap im, int del) {
             image = im;
             delay = del;
         }
    
         public Bitmap image;
         public int delay;
     }
    
     /**
      * Gets display duration for specified frame.
      *
      * @param n
      *          int index of frame
      * @return delay in milliseconds
      */
     public int getDelay(int n) {
         delay = -1;
         if ((n >= 0) && (n < frameCount)) {
             delay = frames.elementAt(n).delay;
             //meets browser compatibility standards
             if (delay < MIN_DELAY_ENFORCE_THRESHOLD) delay = MIN_DELAY;
         }
         return delay;
     }
    
     /**
      * Gets the number of frames read from file.
      *
      * @return frame count
      */
     public int getFrameCount() {
         return frameCount;
     }
    
     /**
      * Gets the first (or only) image read.
      *
      * @return BufferedBitmap containing first frame, or null if none.
      */
     public Bitmap getBitmap() {
         return getFrame(0);
     }
    
     /**
      * Gets the "Netscape" iteration count, if any. A count of 0 means repeat indefinitiely.
      *
      * @return iteration count if one was specified, else 1.
      */
     public int getLoopCount() {
         return loopCount;
     }
    
     /**
      * Creates new frame image from current data (and previous frames as specified by their disposition codes).
      */
     protected void setPixels() {
         // expose destination image's pixels as int array
         int[] dest = new int[width * height];
         // fill in starting image contents based on last image's dispose code
         if (lastDispose > 0) {
             if (lastDispose == 3) {
                 // use image before last
                 int n = frameCount - 2;
                 if (n > 0) {
                     lastBitmap = getFrame(n - 1);
                 } else {
                     lastBitmap = null;
                 }
             }
             if (lastBitmap != null) {
                 lastBitmap.getPixels(dest, 0, width, 0, 0, width, height);
                 // copy pixels
                 if (lastDispose == 2) {
                     // fill last image rect area with background color
                     int c = 0;
                     if (!transparency) {
                         c = lastBgColor;
                     }
                     for (int i = 0; i < lrh; i++) {
                         int n1 = (lry + i) * width + lrx;
                         int n2 = n1 + lrw;
                         for (int k = n1; k < n2; k++) {
                             dest[k] = c;
                         }
                     }
                 }
             }
         }
         // copy each source line to the appropriate place in the destination
         int pass = 1;
         int inc = 8;
         int iline = 0;
         for (int i = 0; i < ih; i++) {
             int line = i;
             if (interlace) {
                 if (iline >= ih) {
                     pass++;
                     switch (pass) {
                     case 2:
                         iline = 4;
                         break;
                     case 3:
                         iline = 2;
                         inc = 4;
                         break;
                     case 4:
                         iline = 1;
                         inc = 2;
                         break;
                     default:
                         break;
                     }
                 }
                 line = iline;
                 iline += inc;
             }
             line += iy;
             if (line < height) {
                 int k = line * width;
                 int dx = k + ix; // start of line in dest
                 int dlim = dx + iw; // end of dest line
                 if ((k + width) < dlim) {
                     dlim = k + width; // past dest edge
                 }
                 int sx = i * iw; // start of line in source
                 while (dx < dlim) {
                     // map color and insert in destination
                     int index = ((int) pixels[sx++]) & 0xff;
                     int c = act[index];
                     if (c != 0) {
                         dest[dx] = c;
                     }
                     dx++;
                 }
             }
         }
         image = Bitmap.createBitmap(dest, width, height, Config.ARGB_4444);
     }
    
     /**
      * Gets the image contents of frame n.
      *
      * @return BufferedBitmap representation of frame, or null if n is invalid.
      */
     public Bitmap getFrame(int n) {
         if (frameCount <= 0)
             return null;
         n = n % frameCount;
         return ((GifFrame) frames.elementAt(n)).image;
     }
    
     /**
      * Reads GIF image from stream
      *
      * @param is
      *          containing GIF file.
      * @return read status code (0 = no errors)
      */
     public int read(InputStream is)
     {
         init();
         if (is != null) {
             in = is;
             readHeader();
             if (!err()) {
                 readContents();
                 if (frameCount < 0) {
                     status = STATUS_FORMAT_ERROR;
                 }
             }
         } else {
             status = STATUS_OPEN_ERROR;
         }
         readComplete = true;
         return status;
     }
    
     public void complete()
     {
         readContents();
         try {
             in.close();
         } catch (Exception e) {
         }
     }
    
     /**
      * Decodes LZW image data into pixel array. Adapted from John Cristy's BitmapMagick.
      */
     protected void decodeBitmapData() {
         int nullCode = -1;
         int npix = iw * ih;
         int available, clear, code_mask, code_size, end_of_information, in_code, old_code, bits, code, count, i, datum, data_size, first, top, bi, pi;
         if ((pixels == null) || (pixels.length < npix)) {
             pixels = new byte[npix]; // allocate new pixel array
         }
         if (prefix == null) {
             prefix = new short[MAX_STACK_SIZE];
         }
         if (suffix == null) {
             suffix = new byte[MAX_STACK_SIZE];
         }
         if (pixelStack == null) {
             pixelStack = new byte[MAX_STACK_SIZE + 1];
         }
         // Initialize GIF data stream decoder.
         data_size = read();
         clear = 1 << data_size;
         end_of_information = clear + 1;
         available = clear + 2;
         old_code = nullCode;
         code_size = data_size + 1;
         code_mask = (1 << code_size) - 1;
         for (code = 0; code < clear; code++) {
             prefix[code] = 0; // XXX ArrayIndexOutOfBoundsException
             suffix[code] = (byte) code;
         }
         // Decode GIF pixel stream.
         datum = bits = count = first = top = pi = bi = 0;
         for (i = 0; i < npix;) {
             if (top == 0) {
                 if (bits < code_size) {
                     // Load bytes until there are enough bits for a code.
                     if (count == 0) {
                         // Read a new data block.
                         count = readBlock();
                         if (count <= 0) {
                             break;
                         }
                         bi = 0;
                     }
                     datum += (((int) block[bi]) & 0xff) << bits;
                     bits += 8;
                     bi++;
                     count--;
                     continue;
                 }
                 // Get the next code.
                 code = datum & code_mask;
                 datum >>= code_size;
                     bits -= code_size;
                     // Interpret the code
                     if ((code > available) || (code == end_of_information)) {
                         break;
                     }
                     if (code == clear) {
                         // Reset decoder.
                         code_size = data_size + 1;
                         code_mask = (1 << code_size) - 1;
                         available = clear + 2;
                         old_code = nullCode;
                         continue;
                     }
                     if (old_code == nullCode) {
                         pixelStack[top++] = suffix[code];
                         old_code = code;
                         first = code;
                         continue;
                     }
                     in_code = code;
                     if (code == available) {
                         pixelStack[top++] = (byte) first;
                         code = old_code;
                     }
                     while (code > clear) {
                         pixelStack[top++] = suffix[code];
                         code = prefix[code];
                     }
                     first = ((int) suffix[code]) & 0xff;
                     // Add a new string to the string table,
                     if (available >= MAX_STACK_SIZE) {
                         break;
                     }
                     pixelStack[top++] = (byte) first;
                     prefix[available] = (short) old_code;
                     suffix[available] = (byte) first;
                     available++;
                     if (((available & code_mask) == 0) && (available < MAX_STACK_SIZE)) {
                         code_size++;
                         code_mask += available;
                     }
                     old_code = in_code;
             }
             // Pop a pixel off the pixel stack.
             top--;
             pixels[pi++] = pixelStack[top];
             i++;
         }
         for (i = pi; i < npix; i++) {
             pixels[i] = 0; // clear missing pixels
         }
     }
    
     /**
      * Returns true if an error was encountered during reading/decoding
      */
     protected boolean err() {
         return status != STATUS_OK;
     }
    
     /**
      * Initializes or re-initializes reader
      */
     protected void init() {
         status = STATUS_OK;
         frameCount = 0;
         frames = new Vector<GifFrame>();
         gct = null;
         lct = null;
     }
    
     /**
      * Reads a single byte from the input stream.
      */
     protected int read() {
         int curByte = 0;
         try {
             curByte = in.read();
         } catch (Exception e) {
             status = STATUS_FORMAT_ERROR;
         }
         return curByte;
     }
    
     /**
      * Reads next variable length block from input.
      *
      * @return number of bytes stored in "buffer"
      */
     protected int readBlock() {
         blockSize = read();
         int n = 0;
         if (blockSize > 0) {
             try {
                 int count = 0;
                 while (n < blockSize) {
                     count = in.read(block, n, blockSize - n);
                     if (count == -1) {
                         break;
                     }
                     n += count;
                 }
             } catch (Exception e) {
                 e.printStackTrace();
             }
             if (n < blockSize) {
                 status = STATUS_FORMAT_ERROR;
             }
         }
         return n;
     }
    
     /**
      * Reads color table as 256 RGB integer values
      *
      * @param ncolors
      *          int number of colors to read
      * @return int array containing 256 colors (packed ARGB with full alpha)
      */
     protected int[] readColorTable(int ncolors) {
         int nbytes = 3 * ncolors;
         int[] tab = null;
         byte[] c = new byte[nbytes];
         int n = 0;
         try {
             n = in.read(c);
         } catch (Exception e) {
             e.printStackTrace();
         }
         if (n < nbytes) {
             status = STATUS_FORMAT_ERROR;
         } else {
             tab = new int[256]; // max size to avoid bounds checks
             int i = 0;
             int j = 0;
             while (i < ncolors) {
                 int r = ((int) c[j++]) & 0xff;
                 int g = ((int) c[j++]) & 0xff;
                 int b = ((int) c[j++]) & 0xff;
                 tab[i++] = 0xff000000 | (r << 16) | (g << 8) | b;
             }
         }
         return tab;
     }
    
     /**
      * Main file parser. Reads GIF content blocks.
      */
     protected void readContents() {
         // read GIF file content blocks
         boolean done = false;
         while (!(done || err())) {
             int code = read();
             switch (code) {
             case 0x2C: // image separator
             readBitmap();
             if(!readComplete) return;
             break;
             case 0x21: // extension
                 code = read();
                 switch (code) {
                 case 0xf9: // graphics control extension
                     readGraphicControlExt();
                     break;
                 case 0xff: // application extension
                     readBlock();
                     String app = "";
                     for (int i = 0; i < 11; i++) {
                         app += (char) block[i];
                     }
                     if (app.equals("NETSCAPE2.0")) {
                         readNetscapeExt();
                     } else {
                         skip(); // don't care
                     }
                     break;
                 case 0xfe:// comment extension
                     skip();
                     break;
                 case 0x01:// plain text extension
                     skip();
                     break;
                 default: // uninteresting extension
                     skip();
                 }
                 break;
             case 0x3b: // terminator
                 done = true;
                 break;
             case 0x00: // bad byte, but keep going and see what happens break;
             default:
                 status = STATUS_FORMAT_ERROR;
             }
         }
     }
    
     /**
      * Reads Graphics Control Extension values
      */
     protected void readGraphicControlExt() {
         read(); // block size
         int packed = read(); // packed fields
         dispose = (packed & 0x1c) >> 2; // disposal method
                     if (dispose == 0) {
                         dispose = 1; // elect to keep old image if discretionary
                     }
                     transparency = (packed & 1) != 0;
                     delay = readShort() * 10; // delay in milliseconds
                     transIndex = read(); // transparent color index
                     read(); // block terminator
     }
    
     /**
      * Reads GIF file header information.
      */
     protected void readHeader() {
         String id = "";
         for (int i = 0; i < 6; i++) {
             id += (char) read();
         }
         if (!id.startsWith("GIF")) {
             status = STATUS_FORMAT_ERROR;
             return;
         }
         readLSD();
         if (gctFlag && !err()) {
             gct = readColorTable(gctSize);
             bgColor = gct[bgIndex];
         }
     }
    
     /**
      * Reads next frame image
      */
     protected void readBitmap() {
         ix = readShort(); // (sub)image position & size
         iy = readShort();
         iw = readShort();
         ih = readShort();
         int packed = read();
         lctFlag = (packed & 0x80) != 0; // 1 - local color table flag interlace
         lctSize = (int) Math.pow(2, (packed & 0x07) + 1);
         // 3 - sort flag
         // 4-5 - reserved lctSize = 2 << (packed & 7); // 6-8 - local color
         // table size
         interlace = (packed & 0x40) != 0;
         if (lctFlag) {
             lct = readColorTable(lctSize); // read table
             act = lct; // make local table active
         } else {
             act = gct; // make global table active
             if (bgIndex == transIndex) {
                 bgColor = 0;
             }
         }
         int save = 0;
         if (transparency) {
             save = act[transIndex];
             act[transIndex] = 0; // set transparent color if specified
         }
         if (act == null) {
             status = STATUS_FORMAT_ERROR; // no color table defined
         }
         if (err()) {
             return;
         }
         decodeBitmapData(); // decode pixel data
         skip();
         if (err()) {
             return;
         }
         frameCount++;
         // create new image to receive frame data
         image = Bitmap.createBitmap(width, height, Config.ARGB_4444);
         setPixels(); // transfer pixel data to image
         frames.addElement(new GifFrame(image, delay)); // add image to frame
         // list
         if (transparency) {
             act[transIndex] = save;
         }
         resetFrame();
     }
    
     /**
      * Reads Logical Screen Descriptor
      */
     protected void readLSD() {
         // logical screen size
         width = readShort();
         height = readShort();
         // packed fields
         int packed = read();
         gctFlag = (packed & 0x80) != 0; // 1 : global color table flag
         // 2-4 : color resolution
         // 5 : gct sort flag
         gctSize = 2 << (packed & 7); // 6-8 : gct size
         bgIndex = read(); // background color index
         pixelAspect = read(); // pixel aspect ratio
     }
    
     /**
      * Reads Netscape extenstion to obtain iteration count
      */
     protected void readNetscapeExt() {
         do {
             readBlock();
             if (block[0] == 1) {
                 // loop count sub-block
                 int b1 = ((int) block[1]) & 0xff;
                 int b2 = ((int) block[2]) & 0xff;
                 loopCount = (b2 << 8) | b1;
             }
         } while ((blockSize > 0) && !err());
     }
    
     /**
      * Reads next 16-bit value, LSB first
      */
     protected int readShort() {
         // read 16-bit value, LSB first
         return read() | (read() << 8);
     }
    
     /**
      * Resets frame state for reading next image.
      */
     protected void resetFrame() {
         lastDispose = dispose;
         lrx = ix;
         lry = iy;
         lrw = iw;
         lrh = ih;
         lastBitmap = image;
         lastBgColor = bgColor;
         dispose = 0;
         transparency = false;
         delay = 0;
         lct = null;
     }
    
     /**
      * Skips variable length blocks up to and including next zero length block.
      */
     protected void skip() {
         do {
             readBlock();
         } while ((blockSize > 0) && !err());
     }
    

    }

you can download the class from https://github.com/Hipmob/gifanimateddrawable/blob/master/src/com/hipmob/gifanimationdrawable/GifAnimationDrawable.java 404 Not Found https://gist.github.com/devunwired/4479231 404 Not Found

If the any above link is not open you can find the class from below link

hope this will save someones time lot because i admire from https://stackoverflow.com/a/11736861/3514144 but i want to show it in imageview

As well if link is unavailable you can find class from Github too.Also if you found any problem leave a comment to this answer i'll try best to help :)

Edit: 12-12-2019

Another way to load gif in custom imageview use this library

Ajay Pandya
  • 2,417
  • 4
  • 29
  • 65
5

Or you can simply add WebView to your xml and load the gif image inside the webview. You donot need to do anything else. The image will loop automatically inside the webview

Sujan Shrestha
  • 419
  • 3
  • 11
5

Glide is the best solution ever. Simply use this code

String gifUrl = "http://part/to/your/gifFile.gif";
Glide  
.with( context )
.load( gifUrl )
.into( imageViewGif );
Illya Bublyk
  • 712
  • 6
  • 21
5

Best and easiest solution to display GIF image in Android and it will work perfectly:

  • Open build.gradle (Module: app)
  • put in dependencies: compile 'pl.droidsonroids.gif:android-gif-drawable:1.1.+'
  • Open layout folder and put this code where you want to display GIF image: e-g activity_main.xml

     <pl.droidsonroids.gif.GifImageView
          android:layout_width="150dp"
          android:layout_height="wrap_content"
          android:src="@drawable/your_gif_file_name"/>
    
  • android:src="@drawable/your_gif_file_name", Replace 'your_gif_file_name' with your desired gif image file

Shujat Munawar
  • 1,657
  • 19
  • 23
3

Unfortunately a gif will not animation inside of an ImageView on its own. You will have to create a new subclass of View to handle this for you.

Show .gif with android.graphics.Movie

Community
  • 1
  • 1
NPike
  • 13,136
  • 12
  • 63
  • 80
3

Use Glide(https://github.com/bumptech/glide):

GlideDrawableImageViewTarget imageViewTarget = new GlideDrawableImageViewTarget(imageview);

        Glide.with(this).load(R.raw.mygif).into(imageViewTarget);
Nirav Sanghvi
  • 408
  • 3
  • 14
2

You should have a look at the Fresco library.

https://github.com/facebook/fresco

shemsu
  • 1,066
  • 9
  • 17