end0tknr's kipple - 新web写経開発

http://d.hatena.ne.jp/end0tknr/ から移転しました

androidのMovieクラスでアニメーションGIFを表示

animated gifを単純にaddViewしても表示されなかったので、ググって写経。

参考url

animated-gifs-in-android

http://code.google.com/p/animated-gifs-in-android/
natineなMovieクラスを利用したもので、nativeな為か動作は軽快です。
ただし、offset値により描画位置を指定したgif画像は表示されないそうです

tomorrowkey

http://d.hatena.ne.jp/tomorrowkey/20100422/1271934492
http://code.google.com/p/android-gifview/
先程のoffset問題を解消する為、自前でgifファイルを解析し、表示します。
こちらは、not nativeな為か軽快な動作ではありませんでした。

私の場合、offsetを持つgif画像は扱わないので、以降では animated-gifs-in-android による実装を写経します。

project file構成

今回、編集または新規作成したファイルのみを記載します

AnimatedGif (project top)
  src/jp.end0tknr.animatedgif/AnimetedGifActivity.java
  src/jp.end0tknr.animatedgif/GifMovieView.java
  res
    drawable/hira_a.gif
    layout/main.xml

layout/main.xml

レイアウトにはLinearLayoutだけを配置し、AnimetedGifActivityからaddView()されます。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
  <LinearLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:id="@+id/ImgContainer"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:layout_gravity="center"
      android:orientation="vertical">
  </LinearLayout>
</LinearLayout>

src/jp.end0tknr.animatedgif/GifMovieView.java

package jp.end0tknr.animetedgif;

import java.io.InputStream;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Movie;
import android.os.SystemClock;
import android.util.Log; 
import android.view.View;
import android.widget.LinearLayout;

public class GifMovieView extends View {

    private Movie mMovie;
	private static final String TAG = "View";
	private boolean roopPlay = false;
	private int disp_co_x = 0;
	private int disp_co_y = 0;
	
    private long mMoviestart;

    public GifMovieView(Context context, InputStream stream) {
        super(context);
        
        mMovie = Movie.decodeStream(stream);        
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(Color.TRANSPARENT);
        super.onDraw(canvas);
        final long now = SystemClock.uptimeMillis();

        if (mMoviestart == 0) { 
            mMoviestart = now;
        }
       
        final int relTime;
        if (roopPlay == true){ //ループする場合
        	relTime = (int)((now - mMoviestart) % mMovie.duration());
        } else {
        	relTime = (int)(now - mMoviestart);
        }
        Log.d(TAG,canvas.getHeight() + " + " + mMovie.height());
        
        final LinearLayout parent = (LinearLayout) getParent();
        //中央に配置
        disp_co_x = (parent.getWidth()- mMovie.width())/2;
        disp_co_y = parent.getTop() + (parent.getHeight()- mMovie.height())/2;

        mMovie.setTime(relTime);
        mMovie.draw(canvas, disp_co_x, disp_co_y);
        this.invalidate();
    }
}

src/jp.end0tknr.animatedgif/AnimetedGifActivity.java

package jp.end0tknr.animetedgif;

import java.io.InputStream;

import jp.end0tknr.animetedgif.GifMovieView;
import jp.end0tknr.animetedgif.R;
import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;

public class AnimetedGifActivity extends Activity {
	private LinearLayout imgContainer = null;
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
		InputStream stream =
				getBaseContext()
				.getResources()
				.openRawResource(R.drawable.hira_a);
		
		GifMovieView gifView = new GifMovieView(this, stream);
		imgContainer = (LinearLayout) findViewById(R.id.ImgContainer);
		imgContainer.addView(gifView);
    }
}


あっ、animetedって、恥ずかしいtypo