我想在我的应用程序中显示动画GIF图像。 我发现Android本身并不支持GIF动画。

但是它可以使用AnimationDrawable显示动画:

开发>指南>图像和图形>绘图概述

这个例子使用动画保存为框架的应用程序资源,但我需要的是直接显示动画gif。

我的计划是将动画GIF分解为帧,并将每帧添加为可绘制的AnimationDrawable。

有人知道如何从动画GIF中提取帧并将它们转换为可绘制的吗?


当前回答

我找到了一个非常简单的方法,这里有一个很好的简单的工作例子

显示动画小部件

在让它工作之前,在代码中有一些更改要做

在下面

    @Override
    public void onCreate(Bundle savedInstanceState){    
        super.onCreate(savedInstanceStated);   
        setContentView(new MYGIFView());
    }    
}

只是替换

setContentView(new MYGIFView());

in

setContentView(new MYGIFView(this));

而在

public GIFView(Context context) {
    super(context);

提供您自己的gif动画文件

    is = context.getResources().openRawResource(R.drawable.earth);
    movie = Movie.decodeStream(is);
}

替换第一行

public MYGIFView(Context context) {

根据课程名称…

在做了这个小改变后,它应该为我工作…

希望这对你有所帮助

其他回答

这是我为在应用程序中显示动图所做的。我扩展了ImageView,这样人们就可以自由地使用它的属性。它可以显示gif从url或资产目录。 这个库还使扩展类从它继承和扩展它来支持不同的方法来初始化gif变得很容易。

https://github.com/Gavras/GIFView

在github页面上有一个小指南。

它也发布在Android Arsenal上:

https://android-arsenal.com/details/1/4947

使用的例子:

从XML:

<com.whygraphics.gifview.gif.GIFView xmlns:gif_view="http://schemas.android.com/apk/res-auto"
        android:id="@+id/main_activity_gif_vie"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:scaleType="center"
        gif_view:gif_src="url:http://pop.h-cdn.co/assets/16/33/480x264/gallery-1471381857-gif-season-2.gif" />

活动中:

    GIFView mGifView = (GIFView) findViewById(R.id.main_activity_gif_vie);

    mGifView.setOnSettingGifListener(new GIFView.OnSettingGifListener() {
                @Override
                public void onSuccess(GIFView view, Exception e) {
                    Toast.makeText(MainActivity.this, "onSuccess()", Toast.LENGTH_SHORT).show();
                }

                @Override
                public void onFailure(GIFView view, Exception e) {

        }
});

以编程方式设置gif:

mGifView.setGifResource("asset:gif1");

滑翔

Image Loader Library for Android,由谷歌推荐。

Glide和毕加索的很相似,但比毕加索的快得多。 Glide比毕加索消耗的内存要少。

格莱德有而毕加索没有的东西

能够将GIF动画加载到一个简单的ImageView可能是Glide最有趣的功能。是的,你不能这样对待毕加索。 一些重要的环节-

https://github.com/bumptech/glide http://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/en

@PointerNull给出了很好的解决方案,但并不完美。它不能在一些大文件的设备上工作,并显示有bug的Gif动画与前ICS版本的delta帧。 我找到了没有这个bug的解决方案。它是带有原生解码到可绘制的库:koral的android-gif-drawable。

关于BitmapDecode例子的一些想法…基本上,它使用了来自android.graphics的古老但毫无特色的Movie类。 在最新的API版本中,您需要关闭硬件加速,如下所述。这是segfaulting对我来说,否则。

<activity
            android:hardwareAccelerated="false"
            android:name="foo.GifActivity"
            android:label="The state of computer animation 2014">
</activity>

下面是BitmapDecode的例子,只缩短了GIF部分。你必须自己制作小部件(视图)并自己绘制。不如ImageView强大。

import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.*;
import android.view.View;

public class GifActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new GifView(this));
    }

    static class GifView extends View {
        Movie movie;

        GifView(Context context) {
            super(context);
            movie = Movie.decodeStream(
                    context.getResources().openRawResource(
                            R.drawable.some_gif));
        }
        @Override
        protected void onDraw(Canvas canvas) {   
            if (movie != null) {
                movie.setTime(
                    (int) SystemClock.uptimeMillis() % movie.duration());
                movie.draw(canvas, 0, 0);
                invalidate();
            }
        }
    }
}

2其他方法,一个用ImageView另一个用WebView可以在这个教程中找到。ImageView方法使用Apache从谷歌代码授权的android-gifview。

如果你想使用Glide加载gif:

Glide.with(this)
        .asGif()
        .load(R.raw.onboarding_layers) //Your gif resource
        .apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.NONE))
        .listener(new RequestListener<GifDrawable>() {
            @Override
            public boolean onLoadFailed(@Nullable @org.jetbrains.annotations.Nullable GlideException e, Object model, Target<GifDrawable> target, boolean isFirstResource) {
                return false;
            }

            @Override
            public boolean onResourceReady(GifDrawable resource, Object model, Target<GifDrawable> target, DataSource dataSource, boolean isFirstResource) {
                resource.setLoopCount(1);
                return false;
            }
        })
        .into((ImageView) view.findViewById(R.id.layer_icons));