Android:URLを指定して大きなアニメーションGIFを表示するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/809878

  •  03-07-2019
  •  | 
  •  

質問

大きなアニメーションgifのURLがあり、アニメーションをストリーミング表示するYouTubeのようなアクティビティを作成したいとします。方法

  1. 画像内のストリーム
  2. 実際のアニメーションで表示しますか?

ImageView は最初のフレームのみを表示するため、答えではありません。

ボーナスはバッファリングステータスにアクセスできるため、ストリーミングサウンドも同期できます-これは YTMND ビューアアプリケーション。パブリックgifファイルをより良い形式にトランスコードするサービスを作成できましたが、追加の依存関係なしにアプリが機能することを望みます。

役に立ちましたか?

解決

ソリューションの一般的なスケッチは、カスタム View を使用して、定期的に Canvas に自分自身を描画する Movie を要求することです。

最初のステップは、 Movie インスタンスを構築することです。 decodeStream と呼ばれるファクトリーがあり、 InputStream を指定してムービーを作成できますが、 UrlConnection からのストリームを使用するだけでは不十分です。これを試みると、ムービーローダーがストリームで reset を呼び出そうとしたときに IOException が返されます。残念ながら、ハッキングは、手動で設定された mark で区切られた BufferedInputStream を使用して、 reset 失敗しません。幸いなことに、 URLConnection は、予想されるデータ量を示すことができます。このハックは、画像全体をメモリにバッファリングする必要があるため、残念です(デスクトップアプリでは問題ありませんが、メモリに制約のあるモバイルデバイスでは深刻な問題です)。

Movie セットアップコードの抜粋です:

URL url = new URL(gifSource);
URLConnection conn = url.openConnection();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
bis.mark(conn.getContentLength());
Movie movie = Movie.decodeStream(bis);
bis.close();

次に、この Movie を表示するビューを作成する必要があります。カスタムの onDraw を備えた View のサブクラスがトリックを実行します(前のコードで作成した Movie にアクセスできると仮定します)。

@Override protected void onDraw(Canvas canvas) {
    if(movie != null) {
        long now = android.os.SystemClock.uptimeMillis();
        int dur = Math.max(movie.duration(), 1); // is it really animated?
        int pos = (int)(now % dur);
        movie.setTime(pos);
        movie.draw(canvas, x, y);
    }
}

ビューは、ヘルプなしでは再描画をトリガーしません。また、 onDraw の最後で invalidate()を盲目的に呼び出すことは、無駄なエネルギーです。別のスレッド(おそらく、画像データのダウンロードに使用したスレッド)で、メッセージをメインスレッドに投稿して、安定した(ただし非常識ではない)ペースでビューを無効にするように要求できます。

Handler handler = new Handler();
new Thread() {
    @Override public void run() {
        // ... setup the movie (using the code from above)
        // ... create and display the custom view, passing the movie

        while(!Thread.currentThread().isInterrupted()) {
            handler.post(new Runnable() {
                public void run(){
                    view.invalidate();
                }
            });
            try {
                Thread.sleep(50); // yields 20 fps
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}.start();

本当に素晴らしいソリューションには、あらゆる種類の甘いプログレスバーとエラーチェックがありますが、核心はここにあります。

他のヒント

BitmapDecode を試しましたか?

APIデモに例がありますこちら

グライド は、これを実現する最も簡単で効率的な方法を証明します。 1行のコード:-

Glide.with(getApplicationContext())
            .load(Uri.parse("https://media1.giphy.com/media/5ziaphcUWGKPu/200.gif"))
            .asGif().placeholder(R.drawable.ic_launcher).crossFade()
            .into(imageView);

結果はこちら:-

ここに画像の説明を入力してください

ここからのGIF http://giphy.com/search/big-gif/3

ここからjarを追加します。- https://github.com/bumptech/glide/releases

たぶん AnimationDrawable はあなたのために働くでしょうか?編集:この投稿がそうであるようなURLからロードしたい場合はそうではありません。ごめんなさい

http://developer.android.com/reference/android/ graphics / drawable / AnimationDrawable.html

GIFの複雑さに依存します。つまり、単純な読み込み/進行インジケータの場合は、GIFを分解し、各画像を個別に保存し、AndroidフレームワークのAnimationDrawableを使用します。

シンプルなプログレスバーの場合、これはエラーが少なくなり、パフォーマンスが向上する可能性があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top