我想在我的应用程序中显示动画GIF图像。 我发现Android本身并不支持GIF动画。
但是它可以使用AnimationDrawable显示动画:
开发>指南>图像和图形>绘图概述
这个例子使用动画保存为框架的应用程序资源,但我需要的是直接显示动画gif。
我的计划是将动画GIF分解为帧,并将每帧添加为可绘制的AnimationDrawable。
有人知道如何从动画GIF中提取帧并将它们转换为可绘制的吗?
我想在我的应用程序中显示动画GIF图像。 我发现Android本身并不支持GIF动画。
但是它可以使用AnimationDrawable显示动画:
开发>指南>图像和图形>绘图概述
这个例子使用动画保存为框架的应用程序资源,但我需要的是直接显示动画gif。
我的计划是将动画GIF分解为帧,并将每帧添加为可绘制的AnimationDrawable。
有人知道如何从动画GIF中提取帧并将它们转换为可绘制的吗?
当前回答
如果你想使用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));
其他回答
最简单的方法-可以考虑下面的代码
我们可以利用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);
//
}
});
}
我已经成功地使用了本文中提出的解决方案,一个名为GifMovieView的类,它呈现一个视图,然后可以显示或添加到特定的ViewGroup中。查看指定文章的第2部分和第3部分中介绍的其他方法。
这种方法的唯一缺点是电影上的反锯齿不是很好(一定是使用“阴暗的”Android电影类的副作用)。然后你最好在你的动画GIF中设置一个纯色的背景。
为了节省资源,有滑翔库。 不知道为什么要使用其他任何东西,特别是webview只显示图像。 Glide是一个完美而简单的库,它可以从gif中准备动画,并将其直接放到imageview中。 gifdrawable句柄动画本身的逻辑。 Gif有lzw压缩原始rgb数据的动画里面。 没有理由复杂的使用webview和管理更多的文件,只显示一个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的实例。由ImageDecoder.createSource创建的源。
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创建位图。
输出:
AnimatedDrawable还支持调整大小,帧和颜色操作
类似于@Leonti说的,但更有深度:
为了解决同样的问题,我所做的是打开GIMP,隐藏除一个层之外的所有层,将其导出为其自己的图像,然后隐藏该层并取消隐藏下一个层,等等,直到每个层都有单独的资源文件。然后我可以在AnimationDrawable XML文件中使用它们作为框架。