3

in my application i am displaying a few gif images which workd perfectly in emulator but when i install the apk file in my smartphone the application works as normal but gif images are not displayed , any explanation why ??

here is my code for the view for gif display

import android.content.Context;
import java.io.InputStream;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Movie;
import android.os.SystemClock;
import android.view.View;

public class GifWebView extends View {
    private Movie mMovie;
    InputStream mStream;
    long mMoviestart;

    public GifWebView(Context context, InputStream stream) {
        super(context);
        mStream = stream;
        mMovie = Movie.decodeStream(mStream);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(Color.TRANSPARENT);
        super.onDraw(canvas);
        final long now = SystemClock.uptimeMillis();

        if (mMoviestart == 0) 
        {
            mMoviestart = now;
        }
        int gif_image_duration = mMovie.duration();
        if(gif_image_duration==0)
        {
            gif_image_duration = 1;
        }
        final int relTime = (int) ((now - mMoviestart) % gif_image_duration);
        mMovie.setTime(relTime);
        mMovie.draw(canvas, 10, 10);
        this.invalidate();
    }
}

and in my activity i call

GifWebView gif_view;// as global var

and in my on create method

    gif_linear_layout = (LinearLayout)findViewById(R.id.gif_linear_layout);
InputStream stream = null;
            try {
                stream = getAssets().open(gif_name);
                //stream = getAssets().open("gif_images").;
            } 
            catch (IOException e) 
            {
                e.printStackTrace();
            }
            gif_view = new GifWebView(this, stream);
            gif_linear_layout.addView(gif_view);

this is how it looks like part 1 : on emulator part 2 : on my smart phon enter image description here

enter image description here

4

11 回答 11

3

这对我来说就像魅力一样:

GifView.java

package com.example.demo;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout.LayoutParams;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

public class GifView extends View {

    public static final int IMAGE_TYPE_UNKNOWN = 0;
    public static final int IMAGE_TYPE_STATIC = 1;
    public static final int IMAGE_TYPE_DYNAMIC = 2;

    public static final int DECODE_STATUS_UNDECODE = 0;
    public static final int DECODE_STATUS_DECODING = 1;
    public static final int DECODE_STATUS_DECODED = 2;

    private GifDecoder decoder;
    private Bitmap bitmap;

    public int imageType = IMAGE_TYPE_UNKNOWN;
    public int decodeStatus = DECODE_STATUS_UNDECODE;

    private int width;
    private int height;

    private long time;
    private int index;

    private int resId;
    private String filePath;

    private boolean playFlag = false;

    int gifImageResourceID;

    public GifView(Context context, AttributeSet attrs) {
        super(context, attrs);
        String namespace = "http://schemas.android.com/apk/res/" + context.getPackageName();
        gifImageResourceID = attrs.getAttributeResourceValue(namespace, "gif_image", 0);

        if (gifImageResourceID != 0) {
            setGifImageResourceID(gifImageResourceID);
        }
    }

    /**
     * Constructor
     */
    public GifView(Context context) {
        super(context);

    }

    private InputStream getInputStream() {
        if (filePath != null)
            try {
                return new FileInputStream(filePath);
            } catch (FileNotFoundException e) {
            }
        if (resId > 0)
            return getContext().getResources().openRawResource(resId);
        return null;
    }

    /**
     * set gif file path
     *
     * @param filePath
     */
    public void setGif(String filePath) {
        Bitmap bitmap = BitmapFactory.decodeFile(filePath);
        setGif(filePath, bitmap);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        if (bitmap != null) {
            setMeasuredDimension(MeasureSpec.getSize(bitmap.getWidth()), MeasureSpec.getSize(bitmap.getHeight()));
        }

    }



    /**
     * set gif file path and cache image
     *
     * @param filePath
     * @param cacheImage
     */
    public void setGif(String filePath, Bitmap cacheImage) {
        this.resId = 0;
        this.filePath = filePath;
        imageType = IMAGE_TYPE_UNKNOWN;
        decodeStatus = DECODE_STATUS_UNDECODE;
        playFlag = false;
        bitmap = cacheImage;
        width = bitmap.getWidth();
        height = bitmap.getHeight();
        android.view.ViewGroup.LayoutParams params = getLayoutParams();
        params.width = width;
        params.height = height;
        setLayoutParams(params);
        play();
    }

    /**
     * set gif resource id
     *
     * @param resId
     */

    public void setGifImageResourceID(int resId) {
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resId);
        setGif(resId, bitmap);
    }

    /**
     * set gif resource id and cache image
     *
     * @param resId
     * @param cacheImage
     */
    public void setGif(int resId, Bitmap cacheImage) {
        this.filePath = null;
        this.resId = resId;
        imageType = IMAGE_TYPE_UNKNOWN;
        decodeStatus = DECODE_STATUS_UNDECODE;
        playFlag = false;
        bitmap = cacheImage;
        width = bitmap.getWidth();
        height = bitmap.getHeight();
        setLayoutParams(new LayoutParams(width, height));
        play();
    }

    private void decode() {
        release();
        index = 0;

        decodeStatus = DECODE_STATUS_DECODING;

        new Thread() {
            @Override
            public void run() {
                decoder = new GifDecoder();
                decoder.read(getInputStream());
                if (decoder.width == 0 || decoder.height == 0) {
                    imageType = IMAGE_TYPE_STATIC;
                } else {
                    imageType = IMAGE_TYPE_DYNAMIC;
                }
                postInvalidate();
                time = System.currentTimeMillis();
                decodeStatus = DECODE_STATUS_DECODED;
            }
        }.start();
    }

    public void release() {
        decoder = null;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (decodeStatus == DECODE_STATUS_UNDECODE) {
            canvas.drawBitmap(bitmap, (getWidth()-width)/2, (getHeight()-height)/2, null);
            if (playFlag) {
                decode();
                invalidate();
            }
        } else if (decodeStatus == DECODE_STATUS_DECODING) {
            canvas.drawBitmap(bitmap, (getWidth()-width)/2, (getHeight()-height)/2, null);
            invalidate();
        } else if (decodeStatus == DECODE_STATUS_DECODED) {
            if (imageType == IMAGE_TYPE_STATIC) {
                canvas.drawBitmap(bitmap, (getWidth()-width)/2, (getHeight()-height)/2, null);
            } else if (imageType == IMAGE_TYPE_DYNAMIC) {
                if (playFlag) {
                    long now = System.currentTimeMillis();

                    if (time + decoder.getDelay(index) < now) {
                        time += decoder.getDelay(index);
                        incrementFrameIndex();
                    }
                    Bitmap bitmap = decoder.getFrame(index);
                    if (bitmap != null) {
                        canvas.drawBitmap(bitmap, (getWidth()-width)/2, (getHeight()-height)/2, null);
                    }
                    invalidate();
                } else {
                    Bitmap bitmap = decoder.getFrame(index);
                    canvas.drawBitmap(bitmap, (getWidth()-width)/2, (getHeight()-height)/2, null);
                }
            } else {
                canvas.drawBitmap(bitmap, (getWidth()-width)/2, (getHeight()-height)/2, null);
            }
        }
    }

    private void incrementFrameIndex() {
        index++;
        if (index >= decoder.getFrameCount()) {
            index = 0;
        }
    }

    private void decrementFrameIndex() {
        index--;
        if (index < 0) {
            index = decoder.getFrameCount() - 1;
        }
    }

    public void play() {
        time = System.currentTimeMillis();
        playFlag = true;
        invalidate();
    }

    public void pause() {
        playFlag = false;
        invalidate();
    }

    public void stop() {
        playFlag = false;
        index = 0;
        invalidate();
    }

    public void nextFrame() {
        if (decodeStatus == DECODE_STATUS_DECODED) {
            incrementFrameIndex();
            invalidate();
        }
    }

    public void prevFrame() {
        if (decodeStatus == DECODE_STATUS_DECODED) {
            decrementFrameIndex();
            invalidate();
        }
    }
}

GifDecoder.java

package com.example.demo;

import java.io.InputStream;
import java.util.Vector;

import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;

public class GifDecoder {
    /**
     * File read status: No errors.
     */
    public static final int STATUS_OK = 0;
    /**
     * File read status: Error decoding file (may be partially decoded)
     */
    public static final int STATUS_FORMAT_ERROR = 1;
    /**
     * File read status: Unable to open source.
     */
    public static final int STATUS_OPEN_ERROR = 2;
    /** max decoder pixel stack size */
    protected static final int MAX_STACK_SIZE = 4096;
    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 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;
        }
        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;
        }
        try {
            is.close();
        } catch (Exception e) {
        }
        return status;
    }

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

如何使用?

将所有图像放在 res/drawable 文件夹而不是资产文件夹中。

    gif_view = new GifWebView(this);
    gif_view.setGifImageResourceID(R.drawable.apple);
    gif_linear_layout.addView(gif_view);
于 2013-10-09T11:14:36.323 回答
1

Android does not natively display animated GIFs. However, you can resort to using the android.graphics.Movie class as explained in this link.

As explained briefly, the feature is lightly discussed in SDK Reference, but used in Samples in ApiDemos in BitmapDecode.

Hope it helps!

于 2013-10-07T06:53:36.620 回答
1

就在几分钟前,有一个类似的问题。这是图片大小的问题。

于 2013-10-08T16:40:54.907 回答
1

将图像放在可绘制文件夹中,然后检查您的信息 android 不支持 gif 动画它只会显示一帧

于 2013-10-08T16:22:38.760 回答
1
 @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(Color.TRANSPARENT);
        super.onDraw(canvas);
        final long now = SystemClock.uptimeMillis();

        if (mMoviestart == 0) 
        {
            mMoviestart = now;
        }
        int gif_image_duration = mMovie.duration();
        if(gif_image_duration==0)
        {
            gif_image_duration = 1;
        }
        final int relTime = (int) ((now - mMoviestart) % gif_image_duration);
        mMovie.setTime(relTime);
        mMovie.draw(canvas, 10, 10);
        this.invalidate();
    }

检查此方法所有错误都在此方法中,这是为了什么canvas.drawColor(Color.TRANSPARENT);以及您之前也调用过它,super.onDraw(canvas);并且还删除了它this.invalidate();并检查

您可以使用此方法从 assest 文件夹加载图像

private Bitmap getBitmapFromAsset(String strName)
    {
        AssetManager assetManager = getAssets();
        InputStream istr = null;
        try {
            istr = assetManager.open(strName);
        } catch (IOException e) {
            e.printStackTrace();
        }
        Bitmap bitmap = BitmapFactory.decodeStream(istr);
        return bitmap;
    }

也检查这些链接:

http://androidosbeginning.blogspot.in/2010/09/gif-animation-in-android.html

为什么 .gif 动画图像在我的 Android 应用程序中没有动画效果?

http://droid-blog.net/2011/10/14/tutorial-how-to-use-animated-gifs-in-android-part-1/

于 2013-10-09T10:47:50.647 回答
1

它不会解决您的问题,但可能会给出提示:

if(stream != null){
    gif_view = new GifWebView(this, stream);
}
else{
  Log.d("tag", "can't load gif image from assets");
}
于 2013-09-29T18:13:34.770 回答
1

愚蠢的问题,但设备上的照片?我知道它们应该在 apk 中,但你永远不知道。Ddms 有一个文件资源管理器,您可能需要设置打开 USB,它们应该在数据/数据中,但可能是数据 sdcard 或某些供应商特定的位置,但您会在某处找到您的项目文件夹

于 2013-10-08T21:04:27.227 回答
1

从屏幕截图来看,您的模拟器和手机似乎都在 Android 4+ 上,但您手机上的框架仍有可能缺少我在此处对另一篇文章的回答中提到的重要提交。也许您可以在带有 Android 2.3.3 (API10) 的模拟器上测试您的应用,看看它在手机上的行为是否与在手机上相同?

至于更可靠的解决方案,也许您可​​以尝试链接帖子中的库或评论中建议的其他方法。

于 2013-10-05T23:12:30.887 回答
1

模拟器的窗口尺寸差异您的智能手机可能没有显示在您的手机上。

mMovie.draw(canvas, 10, 10); // change dimension value and find correct one.
于 2013-09-30T13:48:01.513 回答
0

这是我所做的

第 1 步:在我的布局中创建一个简单的 webview

第 2 步:将 gif 文件保存在 assets 文件夹中

第 3 步:使用

webview.loadDataWithBaseURL("file:///android_asset/","<html style=\"height:90%;width:95%\"><body>" +
                "<img src=\""+gif_char+".gif"+"\" " +
                "style=\"height:100%;width:100%\"></body></html>","text/html", "UTF-8","");

第四步:保持基地位置:file:///android_asset/

是的,动图像魅力一样运行

好吧,我知道这不是对我遇到的问题的解释,但这是我所做的替代解决方案

于 2013-10-10T11:25:52.963 回答
0

我面临同样的问题。如果您确信您的代码没问题,那么只需添加android:hardwareAccelerated="false"您的此活动的清单。希望它能解决你的问题。

于 2014-02-22T12:19:18.713 回答