32

我想在一个 android 应用程序中显示一个动画 GIF 图像,如下图所示。我试过webview,但没有成功。如何在应用程序中显示动画 gif?在此处输入图像描述

4

11 回答 11

31

您还可以使用此库轻松支持gifDrawable

只需使用 GifImageView 而不是普通的 ImageView:

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

并在 src attr 下找到您的 gif 文件。就这样!

于 2015-05-16T16:15:31.943 回答
20

您可以使用滑翔

ImageView imageView = (ImageView) findViewById(R.id.imageView);
GlideDrawableImageViewTarget imageViewTarget = new GlideDrawableImageViewTarget(imageView);
Glide.with(this).load(R.raw.sample_gif).into(imageViewTarget);
于 2016-07-30T13:14:15.487 回答
10

经过长时间的谷歌搜索,我知道没有对 GIF 图像的原生支持。在应用程序中显示动画 gif 没有适当的解决方案。您可以查看此解决方案

使动画 gif 在布局中播放。

于 2012-10-04T17:30:22.693 回答
5

我尝试了很多库来使用 Animated gif 。但是每个图书馆都落后和不堪重负。但是现在,经过一两天的研究,我有了一个使用动画 gif 的想法,并且性能非常好,不滞后不压碎。

解决方案是使用Glide

请按照以下步骤操作。

在 xml 文件中。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#62b849"
    tools:context=".MainActivity">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:id="@+id/splace_image_view"
        android:layout_centerInParent="true"/>

</RelativeLayout> 

在你的java文件中

 ImageView imageView = findViewById(R.id.splace_image_view);

Glide
        .with(this)
        .load(R.drawable.football)
        .into(imageView);
于 2019-06-02T04:40:16.853 回答
4

在 Android 中显示 GIF 图像的最佳和最简单的解决方案,它将完美运行:

  • 打开 build.gradle(模块:app)
  • 放入依赖项: compile 'pl.droidsonroids.gif:android-gif-drawable:1.1.+'
  • 打开布局文件夹并将此代码放在要显示 GIF 图像的位置:例如 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", 将 'your_gif_file_name' 替换为你想要的 gif 图像文件

于 2017-04-11T10:05:42.353 回答
2

您不需要任何库,只需使用以下代码:

第 1 步: 创建一个名为 GIFView.java 的文件

package com.thigale.testproject;

/**
 * Created by Thigale Sameer on 11-12-16.
 */

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

import java.io.InputStream;

public class GifView extends View {
public Movie mMovie;
public long movieStart;
private int gifId;

public GifView(Context context) {
    super(context);
}

public GifView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initializeView(attrs.getAttributeResourceValue("http://schemas.android.com/apk/res-auto", "src", 0));
}

public GifView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    initializeView(attrs.getAttributeResourceValue("http://schemas.android.com/apk/res-auto", "src", 0));
}

private void initializeView(final int id) {
    InputStream is = getContext().getResources().openRawResource(id);
    mMovie = Movie.decodeStream(is);
    this.gifId = id;
}

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

    if (movieStart == 0) {
        movieStart = now;
    }

    if (mMovie != null) {
        int relTime = (int) ((now - movieStart) % mMovie.duration());
        mMovie.setTime(relTime);
        mMovie.draw(canvas, getWidth() - mMovie.width(), getHeight() - mMovie.height());
        this.invalidate();
    }
}

public void setGIFResource(int resId) {
    this.gifId = resId;
    initializeView(this.gifId);
}

public int getGIFResource() {
    return this.gifId;
}
}

第 2 步: 在 res/attrs.xml 中添加以下行

<declare-styleable name="GIFView">
  <attr name="src" format="reference" />
</declare-styleable>

第 3 步: 将此行添加到您的 AndroidManifest.xml 特定活动中

android:hardwareAccelerated="false"

第 4 步: 在您的 XML 中创建此视图:

<com.thigale.testproject.GifView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    components:src="@drawable/loading" />

步骤 5 在您创建视图的父活动中,添加以下行:

xmlns:components="http://schemas.android.com/apk/res-auto"
于 2016-12-11T09:53:53.203 回答
1

我也尝试过这样做,但 Android 不显示带有动画的 gif 图像。如果你想达到同样的效果,那么你需要拍摄几帧动画图像,然后逐帧使用动画。

您可以在下面的链接中参考。 http://developer.android.com/reference/android/graphics/drawable/AnimationDrawable.html

于 2012-10-04T12:17:57.423 回答
0

试试这种方式:

    Movie movie,movie1;
    InputStream is=null,is1=null;
    long moviestart;
    long moviestart1;
    public GIFView(Context context) {
        super(context);
        is=context.getResources().openRawResource(R.drawable.hxps);
        is1=context.getResources().openRawResource(R.drawable.cartoon);
        movie=Movie.decodeStream(is);
        movie1=Movie.decodeStream(is1);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(0xFFCCCCCC);
        super.onDraw(canvas);
        long now=android.os.SystemClock.uptimeMillis();
        System.out.println("now="+now);
         if (moviestart == 0) {   // first time
             moviestart = now;

         }
         if(moviestart1==0)
         {
             moviestart1=now;
         }
         System.out.println("\tmoviestart="+moviestart);
         int relTime = (int)((now - moviestart) % movie.duration()) ;
         int relTime1=(int)((now - moviestart1)% movie1.duration());
         System.out.println("time="+relTime+"\treltime="+movie.duration());
         movie.setTime(relTime);
         movie1.setTime(relTime1);
         movie.draw(canvas,0,0);
         movie1.draw(canvas,10,300);
         this.invalidate();
    }

在此处输入图像描述

于 2015-05-01T08:49:45.910 回答
0

你可以试试这个库GifImageView。它非常简单易用。以下示例代码来自该项目的 README。

@Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState);

gifView = new GifImageView(context);
gifView.setBytes(bitmapData);
setContentView(gifView);

}

@Override protected void onStart() { super.onStart(); gifView.startAnimation(); }

@Override protected void onStop() { super.onStop(); gifView.stopAnimation(); }

于 2015-05-01T08:59:01.690 回答
0

更新:

在android arsenalGIFView的 GitHub 页面中有一个最新版本。

这是当有人要求我帮助他展示 GIF 时我所做的一件小事。我在网上找到的大部分东西都是第三方库和解决方案,它们使用 UI 线程来处理在我的手机上运行不佳的 gif,所以我决定在 android 的 Movie API 的帮助下自己做。我特意让它扩展了 ImageView,这样我们就可以使用 scaleType 之类的属性。这支持从 url 或资产目录中检索 gif。我记录了一切。

如何使用它:

在 xml 布局文件中使用它的简单示例:

<[package].GIFView xmlns:gif_view="http://schemas.android.com/apk/res-auto"
        android:id="@+id/gif_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="center"
        gif_view:gif_src="asset:gif1" />

编码:

GIF.java:

/**
 * Class that represents a gif instance.
 */
public class GIF {

    private static final Bitmap.Config DEF_VAL_CONFIG = Bitmap.Config.RGB_565;

    private static final int DEF_VAL_DELAY_IN_MILLIS = 33;

    // the gif's frames are stored in a movie instance
    private Movie movie;

    // the canvas of this gif
    private Canvas canvas;

    // the bitmap of this gif
    private Bitmap bitmap;

    // the start time of the gif
    private long gifStartTime;

    // the executor of the gif's thread
    private ScheduledExecutorService executor;

    // the main runnable of the gif
    private Runnable mainRunnable;

    // delay in millis between frames
    private int delayInMillis;

    private OnFrameReadyListener onFrameReadyListener;

    private Handler listenerHandler;

    private Runnable listenerRunnable;

    /**
     * Creates Gif instance based on the passed InputStream.
     *
     * @param in the InputStream
     * @throws InputStreamIsNull                        if in is null
     * @throws InputStreamIsEmptyOrUnavailableException if in is empty or unavailable
     */
    public GIF(InputStream in) {
        this(in, DEF_VAL_CONFIG);
    }

    /**
     * Creates Gif instance based on the passed InputStream and the config.
     *
     * @param in     the InputStream
     * @param config the Config
     * @throws NullPointerException                     if config is null
     * @throws InputStreamIsNull                        if in is null
     * @throws InputStreamIsEmptyOrUnavailableException if in is empty or unavailable
     */
    public GIF(InputStream in, Bitmap.Config config) {
        if (in == null)
            throw new InputStreamIsNull("the input stream is null");

        this.movie = Movie.decodeStream(in);

        if (movie == null)
            throw new InputStreamIsEmptyOrUnavailableException("the input steam is empty or unavailable");

        this.bitmap = Bitmap.createBitmap(movie.width(), movie.height(), config);

        // associates the canvas with the bitmap
        this.canvas = new Canvas(bitmap);

        this.mainRunnable = new Runnable() {
            @Override
            public void run() {
                draw();
                invokeListener();
            }
        };

        setDelayInMillis(DEF_VAL_DELAY_IN_MILLIS);
    }

    /**
     * Register a callback to be invoked when the gif changed a frame.
     * Invokes methods from a special thread.
     *
     * @param onFrameReadyListener the listener to attach
     */
    public void setOnFrameReadyListener(OnFrameReadyListener onFrameReadyListener) {
        setOnFrameReadyListener(onFrameReadyListener, null);
    }

    /**
     * Register a callback to be invoked when the gif changed a frame.
     * Invokes methods from the specified handler.
     *
     * @param onFrameReadyListener the listener to attach
     * @param handler              the handler
     */
    public void setOnFrameReadyListener(OnFrameReadyListener onFrameReadyListener, Handler handler) {
        this.onFrameReadyListener = onFrameReadyListener;
        listenerHandler = handler;

        if (listenerHandler != null)
            listenerRunnable = new Runnable() {
                @Override
                public void run() {
                    GIF.this.onFrameReadyListener.onFrameReady(bitmap);
                }
            };

        else
            listenerRunnable = null;
    }

    /**
     * Sets the delay in millis between every calculation of the next frame to be set.
     *
     * @param delayInMillis the delay in millis
     * @throws IllegalArgumentException if delayInMillis is non-positive
     */
    public void setDelayInMillis(int delayInMillis) {
        if (delayInMillis <= 0)
            throw new IllegalArgumentException("delayInMillis must be positive");

        this.delayInMillis = delayInMillis;
    }

    /**
     * Starts the gif.
     * If the gif is already running does nothing.
     */
    public void startGif() {
        if (executor != null)
            return;

        executor = Executors.newSingleThreadScheduledExecutor();

        final int INITIAL_DELAY = 0;
        executor.scheduleWithFixedDelay(mainRunnable, INITIAL_DELAY,
                delayInMillis, TimeUnit.MILLISECONDS);
    }

    /**
     * Stops the gif.
     * If the gif is not running does nothing.
     */
    public void stopGif() {
        if (executor == null)
            return;

        executor.shutdown();

        // waits until the thread is finished
        while (true) {
            try {
                executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
                break;
            } catch (InterruptedException ignored) {
            }
        }

        executor = null;
    }

    // calculates the frame and draws it to the bitmap through the canvas
    private void draw() {
        // if gifStartTime == 0 inits it for the first time
        if (gifStartTime == 0)
            gifStartTime = SystemClock.uptimeMillis();

        long timeElapsed = SystemClock.uptimeMillis() - gifStartTime;

        int timeInGif = (int) (timeElapsed % movie.duration());
        movie.setTime(timeInGif);

        movie.draw(canvas, 0, 0);
    }

    // invokes the listener
    private void invokeListener() {
        if (onFrameReadyListener == null)
            return;

        // if handler was given invokes from it, otherwise invokes from this thread
        if (listenerHandler != null)
            listenerHandler.post(listenerRunnable);
        else
            onFrameReadyListener.onFrameReady(bitmap);
    }

    /**
     * Interface definition for a callback to be invoked when the gif changed a frame.
     */
    public interface OnFrameReadyListener {
        /**
         * Called when the gif changed a frame.
         * <p>
         * Note: If a handler was given with the listener this method
         * invokes from the handler, otherwise this method
         * invokes from a special thread.
         * <p>
         * Note: This bitmap is mutable and used by the gif instance
         * thus it is not recommended to mutate it.
         *
         * @param bitmap the new bitmap of the gif
         */
        void onFrameReady(Bitmap bitmap);
    }

    /**
     * Definition of a runtime exception class to throw when the inputStream is null.
     */
    public static class InputStreamIsNull extends NullPointerException {

        /**
         * Creates a new instance.
         */
        public InputStreamIsNull() {
            super();
        }

        /**
         * * Creates a new instance with a message.
         *
         * @param message the message
         */
        public InputStreamIsNull(String message) {
            super(message);
        }
    }

    /**
     * Definition of a runtime exception class to throw when the inputStream is empty or unavailable.
     */
    public static class InputStreamIsEmptyOrUnavailableException extends RuntimeException {

        /**
         * Creates a new instance.
         */
        public InputStreamIsEmptyOrUnavailableException() {
            super();
        }

        /**
         * * Creates a new instance with a message.
         *
         * @param message the message
         */
        public InputStreamIsEmptyOrUnavailableException(String message) {
            super(message);
        }
    }
}

GIFView.java:

/**
 * A view that can show gifs.
 * <p>
 * XML Attributes:
 * <p>
 * gif_src:
 * A string that represents the gif's source.
 * <p>
 * - If you want to get the gif from a url
 * concatenate the string "url:" with the full url.
 * <p>
 * - if you want to get the gif from the assets directory
 * concatenate the string "asset:" with the full path of the gif
 * within the assets directory. You can exclude the .gif extension.
 * <p>
 * for example if you have a gif in the path "assets/ex_dir/ex_gif.gif"
 * the string should be: "asset:ex_dir/ex_gif"
 * <p>
 * delay_in_millis:
 * A positive integer that represents how many milliseconds
 * should pass between every calculation of the next frame to be set.
 */
public class GIFView extends ImageView {

    public static final String RESOURCE_PREFIX_URL = "url:";
    public static final String RESOURCE_PREFIX_ASSET = "asset:";

    private static final int DEF_VAL_DELAY_IN_MILLIS = 33;

    // the gif instance
    private GIF gif;

    // keeps track if the view is in the middle of setting the gif
    private boolean settingGif;

    private GIF.OnFrameReadyListener gifOnFrameReadyListener;

    private OnSettingGifListener onSettingGifListener;

    // delay in millis between frames
    private int delayInMillis;

    /**
     * Creates a new instance in the passed context.
     *
     * @param context the context
     */
    public GIFView(Context context) {
        super(context);
        init(null);
    }

    /**
     * Creates a new instance in the passed context with the specified set of attributes.
     *
     * @param context the context
     * @param attrs   the attributes
     */
    public GIFView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs);
    }

    // inits the view
    private void init(AttributeSet attrs) {
        this.gifOnFrameReadyListener = new GIF.OnFrameReadyListener() {
            @Override
            public void onFrameReady(Bitmap bitmap) {
                setImageBitmap(bitmap);
            }
        };

        setDelayInMillis(DEF_VAL_DELAY_IN_MILLIS);

        if (attrs != null)
            initAttrs(attrs);
    }

    // inits the view with the specified attributes
    private void initAttrs(AttributeSet attrs) {
        TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(
                attrs, R.styleable.gif_view,
                0, 0);
        try {
            // gets and sets the delay in millis.
            int delayInMillis = typedArray.getInt(R.styleable.gif_view_delay_in_millis,
                    DEF_VAL_DELAY_IN_MILLIS);
            if (delayInMillis != DEF_VAL_DELAY_IN_MILLIS)
                setDelayInMillis(delayInMillis);

            // gets the source of the gif and sets it
            String string = typedArray.getString(R.styleable.gif_view_gif_src);
            if (string != null)
                setGifResource(typedArray.getString(R.styleable.gif_view_gif_src));

        } finally {
            typedArray.recycle();
        }
    }

    /**
     * Register callbacks to be invoked when the view finished setting a gif.
     *
     * @param onSettingGifListener the listener to attach
     */
    public void setOnSettingGifListener(OnSettingGifListener onSettingGifListener) {
        this.onSettingGifListener = onSettingGifListener;
    }

    /**
     * Sets the delay in millis between every calculation of the next frame to be set.
     *
     * @param delayInMillis the delay in millis
     * @throws IllegalArgumentException if delayInMillis is non-positive
     */
    public void setDelayInMillis(int delayInMillis) {
        if (delayInMillis <= 0)
            throw new IllegalArgumentException("delayInMillis must be positive");

        this.delayInMillis = delayInMillis;

        if (gif != null)
            gif.setDelayInMillis(delayInMillis);
    }

    /**
     * Returns true if the view is in the process of setting the gif, false otherwise.
     *
     * @return true if the view is in the process of setting the gif, false otherwise
     */
    public boolean isSettingGif() {
        return settingGif;
    }

    /**
     * Sets the gif of this view and starts it.
     * <p>
     * Note that every exception while setting the gif is only sent to the
     * OnSettingGifListener instance attached to this view.
     * <p>
     * If the view has already begun setting another gif, does nothing.
     * You can query this state with isSettingGif().
     * <p>
     * The string passed must be in the following format:
     * <p>
     * - If you want to get the gif from a url
     * concatenate the string "url:" with the full url.
     * <p>
     * - if you want to get the gif from the assets directory
     * concatenate the string "asset:" with the full path of the gif
     * within the assets directory. You can exclude the .gif extension.
     * <p>
     * You can use the Constants:
     * <p>
     * GIFView.RESOURCE_PREFIX_URL = "url:"
     * GIFView.RESOURCE_PREFIX_ASSET = "asset:"
     * <p>
     * for example if you have a gif in the path "assets/ex_dir/ex_gif.gif"
     * invoke the method like this: setGifResource(GIFView.RESOURCE_PREFIX_ASSET + "ex_dir/ex_gif");
     *
     * @param string the string
     * @throws IllegalArgumentException if the string format is invalid
     */
    public void setGifResource(String string) {
        if (settingGif)
            return;

        // stops the gif if it is running
        if (gif != null)
            gif.stopGif();

        // defines some finals for readability
        final int URL_START_INDEX = RESOURCE_PREFIX_URL.length();
        final int ASSET_START_INDEX = RESOURCE_PREFIX_ASSET.length();
        final String GIF_EXTENSION = ".gif";

        if (string.startsWith(RESOURCE_PREFIX_URL)) {

            // notifies setting gif has started
            settingGif = true;

            // gets the url
            String url = string.substring(URL_START_INDEX);

            new AsyncSettingOfGif() {
                @Override
                protected InputStream getGifInputStream(String url) throws Exception {
                    // gets the input stream from the url
                    return (InputStream) new URL(url).getContent();
                }
            }.execute(url);

        } else if (string.startsWith(RESOURCE_PREFIX_ASSET)) {

            // notifies setting gif has started
            settingGif = true;

            // gets the asset path
            String assetPath = string.substring(ASSET_START_INDEX)
                    .replaceAll("[\\\\/]", File.separator); // replacing file separators
            if (!assetPath.endsWith(GIF_EXTENSION))
                assetPath += GIF_EXTENSION;

            new AsyncSettingOfGif() {
                @Override
                protected InputStream getGifInputStream(String assetPath) throws Exception {
                    // gets the input stream from the assets directory
                    return GIFView.this.getResources().getAssets().open(assetPath);
                }
            }.execute(assetPath);

            // if string format is invalid
        } else {
            throw new IllegalArgumentException("string format is invalid");
        }
    }

    /**
     * Called when the view finished to set the gif
     * or an exception has occurred.
     * If there are no exceptions e is null.
     * <p>
     * Note that the gif can be initialized properly
     * and one or more exceptions can be caught in the way.
     *
     * @param e the Exception
     */
    protected void onFinishSettingGif(Exception e) {
        // notifies setting the gif has finished
        settingGif = false;

        if (gif != null)
            onSuccess();
        else
            onFailure(e);
    }

    // on finish setting the gif
    private void onSuccess() {
        gif.setOnFrameReadyListener(gifOnFrameReadyListener, getHandler());
        gif.setDelayInMillis(delayInMillis);
        startGif();

        if (onSettingGifListener != null)
            onSettingGifListener.onSuccess(this);
    }

    // when an exception has occurred while trying to set the gif
    private void onFailure(Exception e) {
        if (onSettingGifListener != null)
            onSettingGifListener.onFailure(this, e);
    }

    /**
     * Starts the gif.
     * If the gif is already running does nothing.
     *
     * @throws IllegalStateException if the gif has not been initialized yet
     */
    public void startGif() {
        if (gif == null || settingGif)
            throw new IllegalStateException("the gif has not been initialized yet");

        gif.startGif();
    }

    /**
     * Stops the gif.
     * If the gif is not running does nothing.
     *
     * @throws IllegalStateException if the gif has not been initialized yet
     */
    public void stopGif() {
        if (gif == null || settingGif)
            throw new IllegalStateException("the gif has not been initialized yet");

        gif.stopGif();
    }

    /**
     * Interface definition for callbacks to be invoked when setting a gif.
     */
    public interface OnSettingGifListener {

        /**
         * Called when a gif has successfully set.
         *
         * @param view the GIFView
         */
        void onSuccess(GIFView view);

        /**
         * Called when a gif cannot be set.
         *
         * @param view the GIFView
         * @param e    the Exception
         */
        void onFailure(GIFView view, Exception e);
    }

    /**
     * Definition of an Exception class to throw when the view cannot initialize the gif.
     */
    public static class CannotInitGifException extends Exception {

        /**
         * Creates a new instance.
         */
        public CannotInitGifException() {
            super();
        }

        /**
         * * Creates a new instance with a message.
         *
         * @param message the message
         */
        public CannotInitGifException(String message) {
            super(message);
        }
    }

    /**
     * A sub-class of AsyncTask to easily perform an async task of setting a gif.
     * <p>
     * The default implementation of AsyncSettingOfGif.doInBackground() is to try and init the gif
     * from the input stream returned from AsyncSettingOfGif.getGifInputStream() and notify
     * GIFView.onFinishSettingGif() sending to it the exception, if occurred, or null.
     * <p>
     * Implementations of this class should override AsyncSettingOfGif.getGifInputStream()
     * to return the right input stream for the gif based on the string argument.
     * The string argument can be, for example, a url to retrieve the input stream from.
     */
    protected abstract class AsyncSettingOfGif extends AsyncTask<String, Void, Exception> {

        @Override
        protected Exception doInBackground(String... string) {
            CannotInitGifException exceptionToSend = null;

            try (InputStream in = getGifInputStream(string[0])) {
                // tries to init the gif
                gif = new GIF(in);

            } catch (Exception e) {
                // prepares the message of the exception
                String message = e.getMessage();
                if (e instanceof FileNotFoundException)
                    message = "file not found: " + message;

                // prepares the exception to send back
                exceptionToSend = new CannotInitGifException(message);
            }

            return exceptionToSend;
        }

        /**
         * Override this method to return the right input stream for the gif based on the string argument.
         * The string argument can be, for example, a url to retrieve the input stream from.
         *
         * @param string the string
         * @return an InputStream of a gif
         * @throws Exception if an exception has occurred
         */
        protected abstract InputStream getGifInputStream(String string) throws Exception;

        @Override
        protected void onPostExecute(Exception e) {
            onFinishSettingGif(e);
        }
    }
}

资源/值/attrs.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="gif_view">
        <attr name="gif_src" format="string" />
        <attr name="delay_in_millis" format="integer" />
    </declare-styleable>
</resources>
于 2016-12-16T20:11:08.750 回答
0

您可以添加一个 webview 并在其中显示一个 gif 图像,例如:

webView.getSettings().setJavaScriptEnabled(true);
    webView.setWebViewClient(new WebViewClient());
    webView.loadUrl("https://upload.wikimedia.org/wikipedia/commons/thumb/2/2c/Rotating_earth_(large).gif/200px-Rotating_earth_(large).gif");

这将在您的应用程序中显示 gif 图像。

希望能帮助到你!祝你好运!

于 2017-02-03T05:49:52.280 回答