Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在android应用程序中显示动画GIF图像?_Android_User Interface - Fatal编程技术网

如何在android应用程序中显示动画GIF图像?

如何在android应用程序中显示动画GIF图像?,android,user-interface,Android,User Interface,我想在android应用程序中显示动画GIF图像,如下图所示。我尝试过webview,但没有成功。如何在应用程序中显示动画gif?我也尝试过这样做,但Android不显示带有动画的gif图像。如果要实现相同的效果,则需要对动画图像进行几帧处理,然后使用逐帧动画 你可以在下面的链接中找到参考资料。 经过长时间的谷歌搜索,我知道GIF图像没有原生支持。在应用程序中显示动画gif没有合适的解决方案。您可以查看 要在布局中播放动画gif,请尝试以下方法: Movie movie,movie1;

我想在android应用程序中显示动画GIF图像,如下图所示。我尝试过webview,但没有成功。如何在应用程序中显示动画gif?

我也尝试过这样做,但Android不显示带有动画的gif图像。如果要实现相同的效果,则需要对动画图像进行几帧处理,然后使用逐帧动画

你可以在下面的链接中找到参考资料。

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

要在布局中播放动画gif,请尝试以下方法:

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

您可以试试这个库。它非常简单,易于使用。以下示例代码来自此项目的自述文件

@凌驾 创建时受保护的void(最终捆绑包savedInstanceState){ super.onCreate(savedInstanceState)

}

@凌驾 受保护的void onStart(){ super.onStart(); giffiew.startAnimation(); }

@凌驾 受保护的void onStop(){ super.onStop(); gifView.stopAnimation(); }


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

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

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

并在src attr下找到gif文件。就这些

您可以使用:


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

第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;
}
}
第二步: 在res/attrs.xml中添加以下行

<declare-styleable name="GIFView">
  <attr name="src" format="reference" />
</declare-styleable>
第4步: 在XML中创建此视图:

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

更新:

的GitHub页面上和中有最新版本

当有人请我帮助他展示礼物时,我做了一件小事。 我在网上找到的大多数东西都是第三方库和解决方案,它们使用UI线程来处理gif,但在我的手机上效果不太好,所以我决定借助android的电影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);
        }
    }
}
/**
*类,该类表示gif实例。
*/
公共类GIF{
私有静态最终位图.Config DEF_VAL_Config=Bitmap.Config.RGB_565;
专用静态最终整数定义值延迟单位=33;
//gif的帧存储在电影实例中
私人电影;
//这个gif的画布
私人帆布;
//此gif的位图
私有位图;
//gif的开始时间
私人长时间送礼;
//gif线程的执行者
专用ScheduledExecutorService执行器;
//gif的主可运行文件
私有可运行可维护;
//帧间延迟(毫秒)
私有整数延迟毫秒;
私有OnFrameReadyListener OnFrameReadyListener;
私有处理器listenerHandler;
私有可运行侦听器可运行;
/**
*基于传递的InputStream创建Gif实例。
*
*InputStream中的@param
*@如果in为空,则抛出InputStreamIsNull
*@throws InputStreamIsEmptyOrUnavailableException,如果in为空或不可用
*/
公共GIF(输入流输入){
这(在DEF_VAL_CONFIG中);
}
/**
*基于传递的InputStream和配置创建Gif实例。
*
*InputStream中的@param
*@param config配置文件
*@config为null时引发NullPointerException
*@如果in为空,则抛出InputStreamIsNull
*@throws InputStreamIsEmptyOrUnavailableException,如果in为空或不可用
*/
公共GIF(输入流输入,位图.Config){
if(in==null)
抛出新的InputStreamIsNull(“输入流为null”);
this.movie=movie.decodeStream(in);
如果(电影==null)
抛出新的InputStreamIsEmptyOrUnavailableException(“输入蒸汽为空或不可用”);
this.bitmap=bitmap.createBitmap(movie.width(),movie.height(),config);
//将画布与位图关联
this.canvas=新画布(位图);
this.mainRunnable=new Runnable(){
@凌驾
公开募捐{
draw();
invokeListener();
}
};
设置延迟单位为毫秒(定义值延迟单位为毫秒);
}
/**
*注册当gif更改帧时要调用的回调。
*从特殊线程调用方法。
*
*@param onFrameReadyListener要附加的侦听器
*/
public void setOnFrameReadyListener(OnFrameReadyListener OnFrameReadyListener){
setOnFrameReadyListener(onFrameReadyListener,null);
}
/**
*注册当gif更改帧时要调用的回调。
*从指定的处理程序调用方法。
*
*@param onFrameReadyListener要附加的侦听器
*@param handler处理程序
*/
public void setOnFrameReadyListener(OnFrameReadyListener OnFrameReadyListener,处理程序){
this.onFrameReadyListener=onFrameReadyListener;
listenerHandler=handler;
if(listenerHandler!=null)
listenerRunnable=新建Runnable(){
@凌驾
公开募捐{
GIF.this.onFrameReadyListener.onFrameReady(位图);
}
};
其他的
listenerRunnable=null;
}
/**
*设置要设置的下一帧的每次计算之间的延迟(毫秒)。
*
*@param delayInMillis the dela
<com.thigale.testproject.GifView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    components:src="@drawable/loading" />
xmlns:components="http://schemas.android.com/apk/res-auto"
<[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" />
/**
 * 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);
        }
    }
}
/**
 * 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);
        }
    }
}
<?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>
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");
 <pl.droidsonroids.gif.GifImageView
      android:layout_width="150dp"
      android:layout_height="wrap_content"
      android:src="@drawable/your_gif_file_name"/>
<?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> 
 ImageView imageView = findViewById(R.id.splace_image_view);

Glide
        .with(this)
        .load(R.drawable.football)
        .into(imageView);