显示动画GIF

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

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

开发>指南>图像&图形> Drawables概述

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

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

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

428052 次浏览

首先,Android浏览器应该支持动画gif。如果没有,那就是bug!看一下问题跟踪器。

如果你在浏览器外显示这些动画gif,情况可能就不一样了。要做到你所要求的,将需要外部库,支持动画gif解码。

第一个接口是Java2D或JAI (Java Advanced Imaging) API,如果Android Dalvik在你的应用程序中支持这些库,我会感到非常惊讶。

我通过在保存到手机之前将gif动画分割成帧来解决这个问题,这样我就不必在Android中处理它了。

然后我把每一帧下载到手机上,从它创建Drawable,然后创建AnimationDrawable -非常类似于我的问题中的例子

类似于@Leonti说的,但更有深度:

为了解决同样的问题,我所做的是打开GIMP,隐藏除一个层之外的所有层,将其导出为其自己的图像,然后隐藏该层并取消隐藏下一个层,等等,直到每个层都有单独的资源文件。然后我可以在AnimationDrawable XML文件中使用它们作为框架。

Android实际上可以解码和显示动画gif,使用Android。graphics。movie类。

这没有太多的文档,但在SDK参考中。此外,它在ApiDemos中的样本在BitmapDecode中示例中使用了一些动画标志。

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

显示动画小部件

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

在下面

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

只是替换

setContentView(new MYGIFView());

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) {

根据课程名称…

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

希望这对你有所帮助

public class Test extends GraphicsActivity {


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}


private static class SampleView extends View {
private Bitmap mBitmap;
private Bitmap mBitmap2;
private Bitmap mBitmap3;
private Bitmap mBitmap4;
private Drawable mDrawable;


private Movie mMovie;
private long mMovieStart;


// Set to false to use decodeByteArray
private static final boolean DECODE_STREAM = true;


private static byte[] streamToBytes(InputStream is) {
ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
int len;
try {
while ((len = is.read(buffer)) >= 0) {
os.write(buffer, 0, len);
}
} catch (java.io.IOException e) {
}
return os.toByteArray();
}


public SampleView(Context context) {
super(context);
setFocusable(true);


java.io.InputStream is;
is = context.getResources().openRawResource(R.drawable.icon);


BitmapFactory.Options opts = new BitmapFactory.Options();
Bitmap bm;


opts.inJustDecodeBounds = true;
bm = BitmapFactory.decodeStream(is, null, opts);


// now opts.outWidth and opts.outHeight are the dimension of the
// bitmap, even though bm is null


opts.inJustDecodeBounds = false; // this will request the bm
opts.inSampleSize = 4; // scaled down by 4
bm = BitmapFactory.decodeStream(is, null, opts);


mBitmap = bm;


// decode an image with transparency
is = context.getResources().openRawResource(R.drawable.icon);
mBitmap2 = BitmapFactory.decodeStream(is);


// create a deep copy of it using getPixels() into different configs
int w = mBitmap2.getWidth();
int h = mBitmap2.getHeight();
int[] pixels = new int[w * h];
mBitmap2.getPixels(pixels, 0, w, 0, 0, w, h);
mBitmap3 = Bitmap.createBitmap(pixels, 0, w, w, h,
Bitmap.Config.ARGB_8888);
mBitmap4 = Bitmap.createBitmap(pixels, 0, w, w, h,
Bitmap.Config.ARGB_4444);


mDrawable = context.getResources().getDrawable(R.drawable.icon);
mDrawable.setBounds(150, 20, 300, 100);


is = context.getResources().openRawResource(R.drawable.animated_gif);


if (DECODE_STREAM) {
mMovie = Movie.decodeStream(is);
} else {
byte[] array = streamToBytes(is);
mMovie = Movie.decodeByteArray(array, 0, array.length);
}
}


@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(0xFFCCCCCC);


Paint p = new Paint();
p.setAntiAlias(true);


canvas.drawBitmap(mBitmap, 10, 10, null);
canvas.drawBitmap(mBitmap2, 10, 170, null);
canvas.drawBitmap(mBitmap3, 110, 170, null);
canvas.drawBitmap(mBitmap4, 210, 170, null);


mDrawable.draw(canvas);


long now = android.os.SystemClock.uptimeMillis();
if (mMovieStart == 0) { // first time
mMovieStart = now;
}
if (mMovie != null) {
int dur = mMovie.duration();
if (dur == 0) {
dur = 1000;
}
int relTime = (int) ((now - mMovieStart) % dur);
mMovie.setTime(relTime);
mMovie.draw(canvas, getWidth() - mMovie.width(), getHeight()
- mMovie.height());
invalidate();
}
}
}
}


class GraphicsActivity extends Activity {
// set to true to test Picture
private static final boolean TEST_PICTURE = false;


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


@Override
public void setContentView(View view) {
if (TEST_PICTURE) {
ViewGroup vg = new PictureLayout(this);
vg.addView(view);
view = vg;
}


super.setContentView(view);
}
}


class PictureLayout extends ViewGroup {
private final Picture mPicture = new Picture();


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


public PictureLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}


@Override
public void addView(View child) {
if (getChildCount() > 1) {
throw new IllegalStateException(
"PictureLayout can host only one direct child");
}


super.addView(child);
}


@Override
public void addView(View child, int index) {
if (getChildCount() > 1) {
throw new IllegalStateException(
"PictureLayout can host only one direct child");
}


super.addView(child, index);
}


@Override
public void addView(View child, LayoutParams params) {
if (getChildCount() > 1) {
throw new IllegalStateException(
"PictureLayout can host only one direct child");
}


super.addView(child, params);
}


@Override
public void addView(View child, int index, LayoutParams params) {
if (getChildCount() > 1) {
throw new IllegalStateException(
"PictureLayout can host only one direct child");
}


super.addView(child, index, params);
}


@Override
protected LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
}


@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int count = getChildCount();


int maxHeight = 0;
int maxWidth = 0;


for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != GONE) {
measureChild(child, widthMeasureSpec, heightMeasureSpec);
}
}


maxWidth += getPaddingLeft() + getPaddingRight();
maxHeight += getPaddingTop() + getPaddingBottom();


Drawable drawable = getBackground();
if (drawable != null) {
maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
}


setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
resolveSize(maxHeight, heightMeasureSpec));
}


private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx,
float sy) {
canvas.save();
canvas.translate(x, y);
canvas.clipRect(0, 0, w, h);
canvas.scale(0.5f, 0.5f);
canvas.scale(sx, sy, w, h);
canvas.drawPicture(mPicture);
canvas.restore();
}


@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight()));
mPicture.endRecording();


int x = getWidth() / 2;
int y = getHeight() / 2;


if (false) {
canvas.drawPicture(mPicture);
} else {
drawPict(canvas, 0, 0, x, y, 1, 1);
drawPict(canvas, x, 0, x, y, -1, 1);
drawPict(canvas, 0, y, x, y, 1, -1);
drawPict(canvas, x, y, x, y, -1, -1);
}
}


@Override
public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
location[0] = getLeft();
location[1] = getTop();
dirty.set(0, 0, getWidth(), getHeight());
return getParent();
}


@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int count = super.getChildCount();


for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != GONE) {
final int childLeft = getPaddingLeft();
final int childTop = getPaddingTop();
child.layout(childLeft, childTop,
childLeft + child.getMeasuredWidth(),
childTop + child.getMeasuredHeight());


}
}
}
}

我已经成功地使用了提出的解决方案在本文中,一个名为GifMovieView的类,它呈现一个View,然后可以显示或添加到特定的ViewGroup。查看指定文章的第2部分和第3部分中介绍的其他方法。

这种方法的唯一缺点是电影上的反锯齿不是很好(一定是使用“阴暗的”Android Movie类的副作用)。然后你最好在你的动画GIF中设置一个纯色的背景。

使用ImageViewEx,这是一个库,可以使使用gif像使用ImageView一样简单。

把它放到WebView中,它必须能够正确地显示它,因为默认浏览器支持gif文件。(Froyo+,如果我没记错的话)

关于BitmapDecode例子的一些想法…基本上,它使用了来自android.graphics的古老但毫无特色的电影类。 在最近的API版本中,你需要关闭硬件加速如这里所述

<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从谷歌Code授权的android-gifview

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

试试这个,下面的代码在进度条中显示gif文件

loading_activity.xml(在布局文件夹中)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff" >


<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleLarge"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:indeterminate="true"
android:indeterminateDrawable="@drawable/custom_loading"
android:visibility="gone" />


</RelativeLayout>

Custom_loading.xml(在可绘制文件夹中)

这里我把black_gif.gif(在可绘制文件夹),你可以把自己的GIF在这里

<?xml version="1.0" encoding="utf-8"?>
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/black_gif"
android:pivotX="50%"
android:pivotY="50%" />

java(在res文件夹中)

public class LoadingActivity extends Activity {


ProgressBar bar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_loading);
bar = (ProgressBar) findViewById(R.id.progressBar);
bar.setVisibility(View.VISIBLE);


}


}

没有人提到离子滑翔库。它们工作得很好。

与WebView相比,它更容易处理。

在Android上显示动画GIF的方法:

  • 电影类。正如上面提到的,它有很多bug。
  • WebView。它使用起来非常简单,而且通常可以工作。但有时它开始表现不佳,而且总是在一些你没有的晦涩设备上。另外,您不能在任何类型的列表视图中使用多个实例,因为它会对内存产生影响。不过,您可以将其视为主要方法。
  • 自定义代码解码gif为位图,并显示为Drawable或ImageView。我将提到两个库:

https://github.com/koral--/android-gif-drawable - decoder是用C语言实现的,所以它非常高效。

https://code.google.com/p/giffiledecoder -解码器是在Java中实现的,所以它更容易使用。即使是大文件,仍然相当高效。

你还会发现许多基于GifDecoder类的库。这也是一个基于java的解码器,但它是通过将整个文件加载到内存中来工作的,因此它只适用于小文件。

也放(main/assets/ htmlls /name.gif)[用这个HTML调整大小]

<html style="margin: 0;">
<body style="margin: 0;">
<img src="name.gif" style="width: 100%; height: 100%" />
</body>
</html>

在你的Xml中像这样声明(main/res/layout/name.xml):[你定义大小,例如]

<WebView
android:layout_width="70dp"
android:layout_height="70dp"
android:id="@+id/webView"
android:layout_gravity="center_horizontal" />

在你的活动中,把下一个代码放在onCreate里面

web = (WebView) findViewById(R.id.webView);
web.setBackgroundColor(Color.TRANSPARENT); //for gif without background
web.loadUrl("file:///android_asset/htmls/name.html");

如果你想动态加载,你必须用数据加载webview:

// or "[path]/name.gif" (e.g: file:///android_asset/name.gif for resources in asset folder), and in loadDataWithBaseURL(), you don't need to set base URL, on the other hand, it's similar to loadData() method.
String gifName = "name.gif";
String yourData = "<html style=\"margin: 0;\">\n" +
"    <body style=\"margin: 0;\">\n" +
"    <img src=" + gifName + " style=\"width: 100%; height: 100%\" />\n" +
"    </body>\n" +
"    </html>";
// Important to add this attribute to webView to get resource from outside.
webView.getSettings().setAllowFileAccess(true);


// Notice: should use loadDataWithBaseURL. BaseUrl could be the base url such as the path to asset folder, or SDCard or any other path, where your images or the other media resides related to your html
webView.loadDataWithBaseURL("file:///android_asset/", yourData, "text/html", "utf-8", null);
// Or if you want to load image from SD card or where else, here is the idea.
String base = Environment.getExternalStorageDirectory().getAbsolutePath().toString();
webView.loadDataWithBaseURL(base + '/', yourData, "text/html", "utf-8", null);

建议:最好是加载gif静态图像的更多信息检查https://developer.android.com/reference/android/graphics/drawable/AnimationDrawable.html

就是这样,我希望你能帮助我。

目前我们可以使用滑翔 https://github.com/bumptech/glide

我很难让gif动画在Android上运行。我只有以下两个工作:

  1. WebView
  2. 离子

WebView工作正常,非常简单,但问题是它会使视图加载变慢,应用程序会在一秒钟左右失去响应。我不喜欢那样。所以我尝试了不同的方法(不管用):

  1. ImageViewEx已弃用!
  2. 毕加索没有加载动画gif
  3. android-gif-drawable看起来很棒,但它在我的项目中引起了一些有线NDK问题。它导致我本地的NDK库停止工作,我无法修复它

我有一些来回Ion;最后,我让它工作,它真的很快:-)

Ion.with(imgView)
.error(R.drawable.default_image)
.animateGif(AnimateGifMode.ANIMATE)
.load("file:///android_asset/animated.gif");

更新:

使用滑动:

dependencies {
implementation 'com.github.bumptech.glide:glide:4.9.0'
}

用法:

Glide.with(context).load(GIF_URI).into(new DrawableImageViewTarget(IMAGE_VIEW));

看到文档

Glide

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

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

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

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

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

我认为更好的库来处理gif文件是这个是koral写的

使用它,我是成功的,这个库是专用于GIF的;但其中毕加索与滑翔通用图像框架;所以我认为这个库的开发人员完全专注于GIF文件

用壁画。以下是如何做到这一点:

http://frescolib.org/docs/animations.html

以下是示例的回购:

https://github.com/facebook/fresco/tree/master/samples/animation

当心壁画不支持包装内容!

我为在应用程序中显示动图所做的一些事情。我扩展了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");

有两个选项可以将动画gif加载到我们的Android应用程序中

1)使用滑翔将gif加载到ImageView中。

    String urlGif = "https://cdn.dribbble.com/users/263558/screenshots/1337078/dvsd.gif";
//add Glide implementation into the build.gradle file.
ImageView imageView = (ImageView)findViewById(R.id.imageView);
Uri uri = Uri.parse(urlGif);
Glide.with(getApplicationContext()).load(uri).into(imageView);

2)使用html将gif加载到WebView

创建带有。gif文件地址的html:

<html style="margin: 0;">
<body style="margin: 0;">
<img src="https://..../myimage.gif" style="width: 100%; height: 100%" />
</body>
</html>

将这个文件存储到assets目录中:

enter image description here

将这个html加载到应用程序的WebView中:

    WebView webView =  (WebView)findViewById(R.id.webView);
webView = (WebView) findViewById(R.id.webView);
webView.loadUrl("file:///android_asset/html/webpage_gif.html");

这是一个这两个选项的完整示例

enter image description here

最简单的方法-可以考虑下面的代码

我们可以利用Imageview的setImageResource,参考下面的代码相同。

下面的代码可以用来显示像gif一样的图像,如果你有gif的多次分割图像。只需从在线工具中将gif分割成单独的png,并按照以下顺序将图像放入可绘制图中

Image_1.png, image_2.png等等。

让处理程序动态地更改图像。

int imagePosition = 1;
Handler handler = new Handler();
Runnable runnable = new Runnable() {
public void run() {
updateImage();
}
};








public void updateImage() {


appInstance.runOnUiThread(new Runnable() {
@Override
public void run() {
int resId = getResources().getIdentifier("image_" + imagePosition, "drawable", appInstance.getPackageName());
gifImageViewDummy.setImageResource(resId);
imagePosition++;
//Consider you have 30 image for the anim
if (imagePosition == 30) {
//this make animation play only once
handler.removeCallbacks(runnable);


} else {
//You can define your own time based on the animation
handler.postDelayed(runnable, 50);
}


//to make animation to continue use below code and remove above if else
// if (imagePosition == 30)
//imagePosition = 1;
// handler.postDelayed(runnable, 50);
//
}
});
}

< em >下滑4.6 < / em >

1. 加载gif

GlideApp.with(context)
.load(R.raw.gif) // or url
.into(imageview);

2. 来获取文件对象

GlideApp.with(context)
.asGif()
.load(R.raw.gif) //or url
.into(new SimpleTarget<GifDrawable>() {
@Override
public void onResourceReady(@NonNull GifDrawable resource, @Nullable Transition<? super GifDrawable> transition) {


resource.start();
//resource.setLoopCount(1);
imageView.setImageDrawable(resource);
}
});

直接从URL到应用程序布局显示动画GIF的简单方法是使用WebView类。

< p >步骤1: 在你的布局XML

<WebView
android:id="@+id/webView"
android:layout_width="50dp"
android:layout_height="50dp"
/>

步骤2:在活动中

WebView wb;
wb = (WebView) findViewById(R.id.webView);
wb.loadUrl("https://.......);

步骤3:在Manifest.XML中设置Internet权限

<uses-permission android:name="android.permission.INTERNET" />

Step 4: In case you want to make your GIF background transparent and make GIF fit to your Layout

wb.setBackgroundColor(Color.TRANSPARENT);
wb.getSettings().setLoadWithOverviewMode(true);
wb.getSettings().setUseWideViewPort(true);

只是想补充一句,电影类现在已弃用。

这个类在API级别P中已弃用。

建议使用此方法

AnimatedImageDrawable

用于绘制动画图像(如GIF)。

仅适用于android API (android Pie)28和+

使用AnimatedImageDrawable作为

// ImageView from layout
val ima : ImageView = findViewById(R.id.img_gif)
// create AnimatedDrawable
val decodedAnimation = ImageDecoder.decodeDrawable(
// create ImageDecoder.Source object
ImageDecoder.createSource(resources, R.drawable.tenor))
// set the drawble as image source of ImageView
ima.setImageDrawable(decodedAnimation)
// play the animation
(decodedAnimation as? AnimatedImageDrawable)?.start()

XML代码,添加一个ImageView

<ImageView
android:id="@+id/img_gif"
android:background="@drawable/ic_launcher_background" <!--Default background-->
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_width="200dp"
android:layout_height="200dp" />

AnimatedImageDrawable是Drawable的子类,由ImageDecoder.decodeDrawable创建

ImageDecoder.decodeDrawable进一步需要由ImageDecoder.createSource创建的ImageDecoder.Source实例。

ImageDecoder.createSource只能将source作为一个名称,ByteBuffer, File, resourceId, URI, ContentResolver来创建source对象,并使用它来创建AnimatedImageDrawable作为Drawable(多态调用)

static ImageDecoder.Source  createSource(AssetManager assets, String fileName)
static ImageDecoder.Source  createSource(ByteBuffer buffer)
static ImageDecoder.Source  createSource(File file)
static ImageDecoder.Source  createSource(Resources res, int resId)
static ImageDecoder.Source  createSource(ContentResolver cr, Uri uri)

注意:你也可以使用ImageDecoder # decodeBitmap创建Bitmap

输出:

AnimatedDrawable还支持调整大小,帧和颜色操作

如果你想使用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));

保存资源有glide库。 不知道为什么要使用其他任何东西,特别是webview只显示图像。 Glide是一个完美而简单的库,它可以从gif中准备动画,并将其直接放到imageview中。 gifdrawable句柄动画本身的逻辑。 Gif有lzw压缩原始rgb数据的动画里面。 没有理由使用复杂的webview和管理更多的文件来显示应用程序中的gif文件