Animationするぞ

なんか面白いのできた。


AndroidにはAnimationというのがあって、
色々値を決めると勝手にアニメーションしてくれる優れもの。
といいながらあんまり触ってないので実態はよくわからないけど。
気持ちとしてはActionScriptTweenerとかそんな感じ?


ということでいろいろアニメーションさせてみた。
アニメーションの定義自体はサンプルにあるのを使っただけ。でも簡単に自分の好きなアニメーション作れそう。


同時にActionScriptのDisplayObject的なものがあるといいなと思って作った。意外と便利だ。
スケールの変更がうさんくさいのでもうちょっとスマートにしたい。


以下動作画面とソース。
http://screencast.com/t/jPwowtgYt

ソース

package net.swelt.android.animation;

import android.app.Activity;
import android.os.Bundle;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AbsoluteLayout;

import java.util.Vector;

public class AnimationTest extends Activity {
	private final int[] ANIMATION_IDS = {
			R.anim.hyperspace_in, R.anim.hyperspace_out,
			R.anim.push_left_in, R.anim.push_left_out,
			R.anim.push_up_in, R.anim.push_up_out,
			R.anim.shake
	};
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(new AnimationView(this));                
    }
    
    public class AnimationView extends AbsoluteLayout {
    	private Vector<DisplayObject> mObjects;
    	public AnimationView(Context context) {
    		super(context);
    		
    		createObjects();
    	}
    	
    	private void createObjects() {
    		mObjects = new Vector<DisplayObject>();
    		DisplayObject object;
    		
    		int n = (ANIMATION_IDS.length >> 1) + 1;
    		int w, h;
    		for( int i = 0; i < ANIMATION_IDS.length; ++ i ) {
    			object = new DisplayObject(getContext(), R.drawable.kirby, ANIMATION_IDS[i]);
    			mObjects.add(object);
    			object.setScale(0.6f);
    			w = object.getImageWidth();
    			h = object.getImageHeight();
    			object.setLayoutParams(new AbsoluteLayout.LayoutParams(w, h, (i % n) * w, (i / n) * h));
    		}
    		
    		for( int i = 0; i < mObjects.size(); ++ i ) {
    			addView(mObjects.elementAt(i));
    		}
    	}
    	
    	@Override
    	public void onDraw(Canvas canvas) {
    		for( int i = 0; i < mObjects.size(); ++ i ) {
    			mObjects.elementAt(i).invalidate();
    		}
    	}
    	
    }
    
    public class DisplayObject extends View {
    	private Bitmap mBitmap = null;
    	private Animation mAnimation = null;
    	private Rect mSrcRect = null;
    	private Rect mDstRect = null;
    	public DisplayObject(Context context) {
    		super(context);
    	}
    	
    	public DisplayObject(Context context, int id) {
    		super(context);
    		setBitmap(id);
    	}
    	
    	public DisplayObject(Context context, int bid, int aid) {
    		super(context);
    		setBitmap(bid);
    		setAnimation(aid);
    	}
    	
    	public void setBitmap(int id) {
    		mBitmap = BitmapFactory.decodeResource(getContext().getResources(), id);
    		mSrcRect = new Rect(0, 0, mBitmap.width(), mBitmap.height());
    		mDstRect = new Rect(mSrcRect);
    	}
    	
    	public void setAnimation(int id) {
    		mAnimation = AnimationUtils.loadAnimation(getContext(), id);
    	}
    	    	
    	public int getImageWidth() {
    		return mBitmap == null ? 0 : mDstRect.width();
    	}
    	
    	public int getImageHeight() {
    		return mBitmap == null ? 0 : mDstRect.height();
    	}
    	
    	public void setScale(float scale) {
    		if( scale == 1.0f ) {
    			mDstRect.set(mSrcRect);
    		} else {
    			mDstRect.right = (int) (mSrcRect.right * scale);
    			mDstRect.bottom = (int) (mSrcRect.bottom * scale);
    		}
    	}
    	    	
    	@Override
    	public void onDraw(Canvas canvas) {
    		if( mBitmap == null ) return;
    		canvas.drawBitmap(mBitmap, mSrcRect, mDstRect, null);
    	}
    	
    	@Override
    	public boolean onMotionEvent(MotionEvent e) {
    		switch( e.getAction() ) {
    		case MotionEvent.ACTION_DOWN:
    			if( mAnimation != null ) startAnimation(mAnimation);
    			break;
    		}
    		return true;
    	}
    }
}