なお、SurfaceViewはAPI Level1から利用できる。
試しに、適当なサンプルを作成してみる。
1.Activityは最初に生成されるものから変更なし
package com.runpeta.android.angle; import android.app.Activity; import android.os.Bundle; public class RpAngleActivity extends Activity { // アクティビティ作成時に最初に呼ばれる @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } }
2.SurfaceViewのサブクラスを作り、線だけ描画する
package com.runpeta.android.angle; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.view.SurfaceHolder; import android.view.SurfaceView; public class RpAngleSurfaceView extends SurfaceView implements SurfaceHolder.Callback { public RpAngleSurfaceView(Context context) { super(context); getHolder().addCallback(this); } public RpAngleSurfaceView(Context context, AttributeSet attrs) { super(context, attrs); getHolder().addCallback(this); } public RpAngleSurfaceView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); getHolder().addCallback(this); } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } public void surfaceCreated(SurfaceHolder holder) { doDraw(); } public void surfaceDestroyed(SurfaceHolder holder) { } private void doDraw() { // キャンバスをロックする Canvas c = getHolder().lockCanvas(); c.save(); // ここにCanvasに描画処理を書く Paint p = new Paint(); p.setColor(Color.BLACK); c.drawColor(Color.WHITE); c.drawLines(new float[]{20,20,60,60}, p); // キャンバスのロックを解除する c.restore(); getHolder().unlockCanvasAndPost(c); } }
3.メインレイアウトに作成したSurfaceViewを追加します。
・id:surface (とりあえず)
・width:fill_parent
・height:fill_parent
これで線なるものが描画されているハズだ。
これは非常に分かりづらいサンプルになってしまった。
ゲームのように定期的に再描画を行ってみる。
さきほどの"onDraw"をタイマーで定期的に呼び出すために、"ScheduledExecutorService"を利用します。
こんな感じにしようできますので、(定期処理内容)で"onDraw"を呼びます。
// タイマーを開始する ScheduledExecutorService schedule; schedule = Executors.newSingleThreadScheduledExecutor(); schedule.scheduleAtFixedRate(new Runnable(){ public void run() { //定期処理内容 } }, 0, 100, TimeUnit.MILLISECONDS); // タイマーを終了する schedule.shutdown();
さきほどの線がアニメーションで伸び縮みするようにしてみます。
package com.runpeta.android.angle; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.view.SurfaceHolder; import android.view.SurfaceView; public class RpAngleSurfaceView extends SurfaceView implements SurfaceHolder.Callback { private ScheduledExecutorService mSchedule; private Runnable repeatDraw = new Runnable() { public void run() { size += 5; if (size > 400) { size = 100; } doDraw(); } }; private int size = 100; public RpAngleSurfaceView(Context context) { super(context); getHolder().addCallback(this); } public RpAngleSurfaceView(Context context, AttributeSet attrs) { super(context, attrs); getHolder().addCallback(this); } public RpAngleSurfaceView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); getHolder().addCallback(this); } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } public void surfaceCreated(SurfaceHolder holder) { doDraw(); mSchedule = Executors.newSingleThreadScheduledExecutor(); mSchedule.scheduleAtFixedRate(repeatDraw, 0, 100, TimeUnit.MILLISECONDS); } public void surfaceDestroyed(SurfaceHolder holder) { mSchedule.shutdown(); mSchedule = null; } private void doDraw() { // キャンバスをロックする Canvas c = getHolder().lockCanvas(); c.save(); // ここにCanvasに描画処理を書く Paint p = new Paint(); p.setColor(Color.BLACK); c.drawColor(Color.WHITE); c.drawLines(new float[]{20,20,size,size}, p); // キャンバスのロックを解除する c.restore(); getHolder().unlockCanvasAndPost(c); } }
こんな感じで描画ができることが分かったので、後はCanvasとPaintの使い方次第でいろいろ描画できます。
0 件のコメント:
コメントを投稿