2013-05-10 30 views
11

Bố cục của tôi có nhiều lần xem hình ảnh. Tôi muốn hiển thị .gif tệp hoạt ảnh chỉ trong một lần xem hình ảnh. Tôi đã thử phương pháp Yash (Adding gif image in an ImageView in android) nhưng tệp .gif hiển thị tất cả bố cục. Các quan điểm khác biến mất.Cách hiển thị tệp .gif trong imageview?

Tôi muốn hiển thị tất cả.

Bất kỳ ý tưởng nào?

+0

Hãy cho chúng tôi biết một số mã, chúng tôi có thể nắm bắt được bằng cách xem bố cục xml của bạn) và giới hạn màn hình. – MarsAtomic

+0

Tôi nhận được giải pháp, tham khảo liên kết này. http://stackoverflow.com/questions/3660209/display-animated-gif/23670399#23670399 –

+0

Bản sao có thể có của [Thêm hình ảnh gif trong ImageView trong android] (http://stackoverflow.com/questions/ 6533942/add-gif-image-in-an-imageview-in-android) – msangel

Trả lời

2

Thật không may là một hình ảnh động sẽ không hoạt ảnh bên trong ImageView. Bạn sẽ phải tạo một lớp con mới của Chế độ xem để xử lý điều này cho bạn.

Show .gif with android.graphics.Movie

4

Hoặc bạn chỉ có thể thêm WebView để xml của bạn và tải hình ảnh gif bên trong webview. Bạn donot cần phải làm bất cứ điều gì khác. Hình ảnh sẽ tự động lặp lại bên trong chế độ xem web

8

Đặt tập tin .gif của bạn vào res/thư mục thô, trong đoạn hoặc hoạt động của bạn và hơn bạn có thể thiết lập gif trong ImageView như

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; } 
} 

2) 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()); 
    } 
} 

bạn có thể tải về các lớp từ 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

Nếu liên kết bất kỳ ở trên không mở cửa, bạn có thể tìm thấy những lớp từ bên dưới liên kết

niềm hy vọng này sẽ tiết kiệm rất nhiều thời gian bởi vì tôi ngưỡng mộ từ https://stackoverflow.com/a/11736861/3514144 nhưng tôi muốn hiển thị nó trong imageview

Cũng như liên kết là không có ailable bạn có thể tìm thấy lớp học từ Github quá.

+4

Dude, điều này nên được trên github, nó làm việc tốt hơn so với Glide và Fresco - tôi có sự cho phép của bạn để tạo ra một lib bên thứ 3 nhỏ cho nó? –

+0

bạn đùa phải không? ok cho phép lol :) –

+1

@royiby Vui lòng chia sẻ liên kết đến thư viện nếu bạn đã tạo. – Sandeep

1

Glide là giải pháp tốt nhất từ ​​trước tới nay. Đơn giản chỉ cần sử dụng mã này

String gifUrl = "http://part/to/your/gifFile.gif"; 
Glide 
.with(context) 
.load(gifUrl) 
.into(imageViewGif); 
3

Sử dụng Glide (https://github.com/bumptech/glide):

GlideDrawableImageViewTarget imageViewTarget = new GlideDrawableImageViewTarget(imageview); 

     Glide.with(this).load(R.raw.mygif).into(imageViewTarget); 
1

giải pháp tốt nhất và dễ dàng nhất để hiển thị hình ảnh GIF trong Android và nó sẽ làm việc một cách hoàn hảo:

  • mở xây dựng. gradle (Module: app)
  • đưa vào phụ thuộc: biên dịch 'pl.droidsonroids.gif: an droid-gif-drawable: 1.1. + '
  • Mở thư mục bố cục và đặt mã này vào nơi bạn muốn hiển thị hình ảnh GIF: 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", Thay thế 'your_gif_file_name' với mong muốn tập tin ảnh gif của bạn

1

Tôi đã có một vấn đề tương tự rất gần đây .. Chỉ cần thêm này để phụ thuộc của bạn và tạo ImageView duy nhất của bạn:

compile 'pl.droidsonroids.gif:android-gif-drawable:1.2.0' 

Hoạt động rất hiệu quả với các dòng mã tối thiểu. Ví dụ:

<pl.droidsonroids.gif.GifImageView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:id="@+id/dancer" 
     android:src="@drawable/maddancer" /> 
Các vấn đề liên quan