AndroidではSurface ViewとCanvasを使ってアニメーションを描きます

4309 ワード

実際には、各ビューにCanvasがアニメーションを描くことができます.このビューにonDraw()メソッドをリロードするだけでいいのですが、Surface Viewクラスはアニメーションを制動するためのクラスです.
Canvas(中国語で「キャンバス」という)は、HTML 5のcanvasタグと同様に一定の領域で図形を自由に描くことができます.Canvas+SurfaceViewが制作したアニメーションは、ゲーム画面やカメラの画像表示など、ViewAnimationやProperty Animationのようなアニメーションよりも大量の集中再生に適しています.
Surface Viewは一般的に別のスレッドでインタフェースを再描画し続けるためです.そのため、他のアニメーションのようにメインスレッド(UIスレッド)でアニメーションを再生するのと同じ時間に、ユーザーの入力に応答するために一定のスムーズさを消費する必要はありません.
Surface Viewを使用する場合は、次の点に注意してください.
1)各SurfaceViewは、SurfaceViewのライフサイクルを処理し、このSurfaceViewのCanvasオブジェクトを取得するために1つのSurfaceHolderオブジェクトを必要とし、SurfaceViewのgetHolder()メソッドを呼び出してそのSurfaceHolderオブジェクトを取得することができる.
2)SurfaceViewを使用する場合は通常SurfaceViewを継承することにより実現されるが、ついでにimplementsの2つのインターフェース、それぞれRunnableとSurfaceHolderである.Callback.2番目のインタフェースには3つの関数をリロードする必要があります.この3つの関数はSurface Viewのライフサイクル処理であり、Surface HolderオブジェクトのaddCallback()メソッドによって実現されたCallbackオブジェクトを転送することができます.
3)Surface ViewのCanvasを使用する場合は、必ず同期をロックしてください.キャンバスが同時に複数のパターンを描くことができないため、このSurface ViewのSurface HolderオブジェクトのlockCanvas()を呼び出すことでこれを行うことができます.描画が完了すると、SurfaceHolderオブジェクトを呼び出すunlockCanvasAndPost()メソッドがロック解除され、更新されます.
以下に、Surface ViewとCanvasでアニメーションを描画する例を示します.一般的には、直接コピーすると表示効果が実行されます.
package com.example.canvastest;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;

public class MainActivity extends Activity {
	/*
	 *            ,           
	 */
	class GameObject {
		private float x;
		private float y;
		private Bitmap img;
		private Paint paint;

		public GameObject() {
			this.img = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
			this.x = 100;
			this.y = 100;
			this.paint = new Paint();
		}

		//  SurfaceView          Canvas     
		public void drawSelf(Canvas canvas) {
			canvas.drawBitmap(img, x, y, paint);
		}

		//              (          400         )
		public void getNextPos() {
			if (y == 100 && x != 500)
				x += 5;
			else if (x == 500 && y != 500)
				y += 5;
			else if (y == 500 && x != 100)
				x -= 5;
			else if (x == 100 && y != 100)
				y -= 5;
		}
	}

	/*
	 *         SurfaceView    ,                   
	 */
	class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable {
		private Thread thread; // SurfaceView                
		private Canvas canvas;
		private SurfaceHolder surfaceHolder;

		private GameObject obj;

		public MySurfaceView(Context c) {
			super(c);
			this.surfaceHolder = this.getHolder();
			this.surfaceHolder.addCallback(this);
			this.obj = new GameObject();
		}

		@Override
		public void run() {
			while (true) {
				obj.getNextPos();
				canvas = this.surfaceHolder.lockCanvas(); //   lockCanvas      SurfaceView   
				canvas.drawColor(Color.BLACK);
				obj.drawSelf(canvas); //  SurfaceView       。                     
				this.surfaceHolder.unlockCanvasAndPost(canvas); //             
				try {
					Thread.sleep(10); //          ,          
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}

		@Override
		public void surfaceDestroyed(SurfaceHolder arg0) {
			Toast.makeText(getApplicationContext(), "SurfaceView    ", Toast.LENGTH_LONG).show();
		}

		@Override
		public void surfaceCreated(SurfaceHolder arg0) {
			Toast.makeText(getApplicationContext(), "SurfaceView    ", Toast.LENGTH_LONG).show();
			this.thread = new Thread(this);
			this.thread.start();
		}

		@Override
		public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
			//    SurfaceView            
		}
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(new MySurfaceView(getApplicationContext())); //                  SurfaceView
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
}

転載する場合は出典を明記してください.http://blog.csdn.net/gophers