私のアプリケーションではアニメーションGIF画像を表示したいです。私がAndroidがアニメーションGIFをネイティブにサポートしていない難しい方法を見つけたので。
ただし、 AnimationDrawable を使用してアニメーションを表示できます。
開発>ガイド>画像とグラフィック> Drawablesの概要
この例では、アプリケーションリソースにフレームとして保存されたアニメーションを使用していますが、必要なのはanimated gifを直接表示することです。
私の計画は、アニメーションGIFをフレームに分割し、各フレームを描画可能としてAnimationDrawableに追加することです。
アニメーションGIFからフレームを抽出し、それぞれを Drawable に変換する方法を知っている人はいますか?
Androidは、実際にはAndroid.graphics.Movieクラスを使用して、アニメーションGIFをデコードして表示することができます。
これはあまり文書化されていませんが、 SDK Reference にあります。さらに、これは ApiDemosのBitmapDecode exampleのサンプルで、いくつかのアニメーションフラグとともに使用されます。
アップデート:
グライドを使う:
dependencies {
implementation 'com.github.bumptech.glide:glide:4.0.0'
}
使用法:
Glide.with(context).load(GIF_URI).into(new GlideDrawableImageViewTarget(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" />
あなたのアクティビティの中で次のコードをonCreateの中に入れてください
web = (WebView) findViewById(R.id.webView);
web.setBackgroundColor(Color.TRANSPARENT); //for gif without background
web.loadUrl("file:///Android_asset/htmls/name.html");
動的にロードしたい場合は、Webビューにデータをロードする必要があります。
// 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
それはそれです、私はあなたが助けることを願っています。
私はそれを電話に保存する前に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);
あなた自身のgifアニメーションファイルを提供する
is = context.getResources().openRawResource(R.drawable.earth);
movie = Movie.decodeStream(is);
}
最初の行を置き換えます
public MYGIFView(Context context) {
クラスの名前に従って...
この小さな変更を行った後は、私の場合と同じように動作するはずです。
この助けを願って
Android上でアニメーションGIFを表示する方法:
https://github.com/koral--/Android-gif-drawable - デコーダはCで実装されているので非常に効率的です。
https://code.google.com/p/giffiledecoder - デコーダはJavaで実装されているため、操作が簡単です。大きなファイルでも、まだかなり効率的です。
GifDecoderクラスをベースにしたライブラリもたくさんあります。これはJavaベースのデコーダでもありますが、ファイル全体をメモリにロードすることで機能するので、小さいファイルにしか適用できません。
私は、アニメーションGIFをAndroidで動作させるのに本当に苦労しました。私は以下の2つの作業しかしていませんでした。
WebViewは問題なく動作しますが、問題はビューの読み込みが遅くなり、アプリが1秒ほど応答しなくなることです。私はそれが好きではありませんでした。だから私は異なるアプローチを試してみました(うまくいかなかった):
私はIon
とやり取りしました。最後に、私はそれを動かしています、そしてそれは本当に速いです:-)
Ion.with(imgView)
.error(R.drawable.default_image)
.animateGif(AnimateGifMode.ANIMATE)
.load("file:///Android_asset/animated.gif");
ImageViewEx を使用すると、gifをImageView
を使用するのと同じくらい簡単に使用できます。
これを試して、プログレスバーに以下のコード表示GIFファイル
loading_activity.xml(Layoutフォルダ内)
<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%" />
LoadingActivity.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);
}
}
提案されたソリューションで成功しました この記事内 、GifMovieView
と呼ばれるクラスは、View
を表示し、特定のViewGroup
に表示または追加できます。指定された記事のパート2および3に記載されている他の方法を確認してください。
この方法の唯一の欠点は、ムービーのアンチエイリアスがそれほど良くないことです( "shady" Android Movie
Classを使用することの副作用である必要があります)。その後、アニメーションGIF内で背景を単色に設定することをお勧めします。
@PointerNullは良い解決策を示しましたが、完璧ではありません。大きなファイルがあるいくつかのデバイスでは動作せず、バージョン[ICSのバージョンではデルタフレームでバグのあるGifアニメーションを表示します。私はこのバグのない解決策を見つけました。それはdrawableへのネイティブデコードを備えたライブラリです: koralのAndroid-gif-drawable 。
グライド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);
}
});
BitmapDecodeの例についてのいくつかの考え...基本的にそれは古代の、しかしむしろ機能のない Movie Android.graphicsからのクラスを使用します。最近のAPIバージョンでは、ハードウェアアクセラレーションを無効にする必要があります。 に記載されています。そうでなければそれは私にとって偏見だった。
<activity
Android:hardwareAccelerated="false"
Android:name="foo.GifActivity"
Android:label="The state of computer animation 2014">
</activity>
これは、GIF部分だけで短縮されたBitmapDecodeの例です。あなたはあなた自身のウィジェット(ビュー)を作り、自分でそれを描く必要があります。 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();
}
}
}
}
ImageViewを使う方法とWebViewを使う方法の2つの方法が このすばらしいチュートリアル にあります。 ImageViewメソッドは、Google CodeのApacheライセンスの Android-gifview を使用します。
デフォルトのブラウザはgifファイルをサポートしているので、それをWebViewに入れると、正しく表示できなければなりません。 (Froyo +、間違えていなければ)
私たちのAndroidアプリにアニメーションGIFを読み込むには2つのオプションがあります。
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>
このファイルをassetディレクトリに保存します。
このHTMLをアプリケーションのWebViewにロードします。
WebView webView = (WebView)findViewById(R.id.webView);
webView = (WebView) findViewById(R.id.webView);
webView.loadUrl("file:///Android_asset/html/webpage_gif.html");
Heresは、この2つのオプションの完全な例です。
フレスコ画を使用してください。これを行う方法は次のとおりです。
http://frescolib.org/docs/animations.html
これがサンプルのリポジトリです。
https://github.com/facebook/fresco/tree/master/samples/animation
フレスコ画はラップコンテンツをサポートしていません。
私はgifファイルを処理するためのより良いライブラリが これだと思います:by koral
それを使用し、私は成功しているとこのライブラリはGIFに捧げられています。しかし、ピカソとグライドは汎用画像フレームワークです。だから私はこのライブラリの開発者は完全にGIFファイルに集中していると思います
Movie クラスが非推奨になったことを付け加えたいと思いました。
このクラスはAPIレベルPで廃止されました。
これを使用することをお勧めします
アニメーション画像(GIFなど)を描画するために描画可能です。
アプリでGIFを表示するためにしたことがあります。私はImageViewを拡張して、人々がその属性を自由に使えるようにしました。それはurlから、またはassetsディレクトリからGIFを表示することができます。このライブラリはまた、クラスを継承してgifを初期化するためのさまざまなメソッドをサポートするように拡張することを容易にします。
https://github.com/Gavras/GIFView
Githubページにちょっとしたガイドがあります。
Androidアーセナルでも公開されました。
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");
最も簡単な方法 - 以下のコードを検討することができます
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);
//
}
});
}
まず第一に、AndroidブラウザはアニメーションGIFをサポートするはずです。そうでなければ、それはバグです!課題追跡システムを見てください。
これらのアニメーションGIFをブラウザの外側に表示している場合は、別の話になるかもしれません。あなたが頼んでいることをするには、アニメーションGIFのデコードをサポートする外部ライブラリが必要になるでしょう。
AndroidのDalvikがあなたのAppでこれらのライブラリをサポートするのであれば、私は非常に驚きますが、最初の電話はJava2DまたはJAI(Java Advanced Imaging)APIを見ることです。
私はGIFをフレームに分割して標準のAndroidアニメーションを使うことでこれを解決しました
@Leontiが言ったことと似ていますが、もう少し詳しく説明します。
同じ問題を解決するためにGIMPを開き、1つを除くすべてのレイヤーを非表示にし、それを独自の画像としてエクスポートしてから、そのレイヤーを非表示にして次のレイヤーを非表示にするなどしました。それから、それらをAnimationDrawable XMLファイルのフレームとして使用できます。
URLからアプリケーションのレイアウトに直接アニメーションGIFを表示する簡単な方法はWebViewクラスを使用することです。
ステップ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にインターネットの許可を作ります
<uses-permission Android:name="Android.permission.INTERNET" />
ステップ4:GIFの背景を透明にしてGIFをレイアウトに合わせたい場合
wb.setBackgroundColor(Color.TRANSPARENT);
wb.getSettings().setLoadWithOverviewMode(true);
wb.getSettings().setUseWideViewPort(true);