我想在我的应用程序中显示动画GIF图像。但很遗憾,Android不支持原生的动画GIF。
不过,Android可以使用AnimationDrawable来显示动画:
示例使用应用程序资源中保存为帧的动画,但我需要直接显示动画GIF。
我的计划是将动画GIF拆分为帧并将每个帧作为drawable添加到AnimationDrawable中。
有人知道如何从动画GIF中提取帧,并将每个帧转换为Drawable吗?
我想在我的应用程序中显示动画GIF图像。但很遗憾,Android不支持原生的动画GIF。
不过,Android可以使用AnimationDrawable来显示动画:
示例使用应用程序资源中保存为帧的动画,但我需要直接显示动画GIF。
我的计划是将动画GIF拆分为帧并将每个帧作为drawable添加到AnimationDrawable中。
有人知道如何从动画GIF中提取帧,并将每个帧转换为Drawable吗?
实际上Android可以使用android.graphics.Movie类解码和显示动画GIF。
这方面的文档不是很多,但在SDK参考文档中有相关说明。此外,在ApiDemos的BitmapDecode示例中,也使用了一些动画标志。
setLayerType(LAYER_TYPE_SOFTWARE)
。但仍然只适用于某些gif和某些设备。 - Michał KlimczakPaint p = new Paint(); p.setAntiAlias(true); setLayerType(LAYER_TYPE_SOFTWARE, p);
生效了! - Chloe更新:
使用Glide:
dependencies {
implementation 'com.github.bumptech.glide:glide:4.9.0'
}
使用方法:
Glide.with(context).load(GIF_URI).into(new DrawableImageViewTarget(IMAGE_VIEW));
还可以将(main/assets/htmls/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" />
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动画分解成帧,然后保存到手机上,这样在Android中就不必处理它了。
然后我将每一帧下载到手机上,从中创建Drawable,再创建AnimationDrawable - 这与我的问题示例非常相似。
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceStated);
setContentView(new MYGIFView());
}
}
setContentView(new MYGIFView());
setContentView(new MYGIFView(this));
AND IN
public GIFView(Context context) {
super(context);
is = context.getResources().openRawResource(R.drawable.earth);
movie = Movie.decodeStream(is);
}
public MYGIFView(Context context) {
Glide 4.6
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);
}
});
我在Android上很难让动画GIF工作,只有以下两个方法可行:
WebView效果还不错,而且非常简单,但问题是它会使视图加载变慢,应用程序可能会失去响应一两秒钟。我不喜欢这样。所以我尝试了不同的方法(没有成功):
我和Ion
反复尝试之后,最终让它正常工作了,并且速度非常快 :-)
Ion.with(imgView)
.error(R.drawable.default_image)
.animateGif(AnimateGifMode.ANIMATE)
.load("file:///android_asset/animated.gif");
在Android上展示动态GIF的方法:
https://github.com/koral--/android-gif-drawable - 该解码器是用C实现的,因此非常高效。
https://code.google.com/p/giffiledecoder - 该解码器是用Java实现的,因此更易于处理。即使在大文件的情况下,它仍然相当有效。
您还将找到许多基于GifDecoder类的库。这也是一种基于Java的解码器,但它通过将整个文件加载到内存中来工作,因此只适用于小文件。
<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,位于drawable文件夹中)
在这里我放置了黑色gif动画(black_gif.gif,位于drawable文件夹中),你也可以在此处放置自己的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%" />
LoadingActivity.java(in res folder)
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);
}
}