SurfaceViewの基本が分かったところで、関連する重要なクラスとメソッドをまとめておきます。
表1 SurfaceViewに関連する重要なクラスとメソッド | ||||||||||||||||||||||||
|
SurfaceHolderのlockCanvas()には、オーバーロードされたメソッドlockCanvas(Rect)があり、そちらは描画範囲を限定する場合に使用します。描画範囲は、狭ければ狭いほど高速に描画が完了するので、可能なら使うとよいでしょう。
Canvasのメソッドsave()とrestore()は、Java SEやJava MEのCanvasにはない概念なので、紹介しておきます。
Canvas#save()は呼び出された状態を内部スタックに保存し、Canvas#restore()でスタックから保存された状態を復元します。下記サンプルは状態保存後、45度回転させて文字を描画し、元の状態に戻しています。
void doDraw() { Canvas canvas = getHolder().lockCanvas(); canvas.save(); // ★ここで状態を保存 canvas.rotate(45.0f); Paint paint = new Paint(); canvas.drawColor(Color.WHITE); paint.setColor(Color.BLUE); paint.setAntiAlias(true); paint.setTextSize(24); canvas.drawText("Hello, SurfaceView!", paint.getTextSize(), 0, paint); canvas.restore(); // ★ここで状態を復元 getHolder().unlockCanvasAndPost(canvas); }
こうすることで、文字だけが45度回転して描画されたことになります。
状態はスタックに保存されるので、繰り返しsave()を呼び出しても構いません。保存される状態は、クリップとマトリックスです。保存する状態を選択するsave(int)、状態をまとめて戻すrestoreToCount(int)などもあります。
Paintクラスにあるアンチエイリアス機能は、速度とのトレードオフですが、特に文字列描画の際には設定した方がいいでしょう。
図3はアンチエイリアスを設定した場合としていない場合のサンプルです。テキストは上段がアンチエイリアスなし、下がアンチエイリアスありです。視認性がかなり向上しているのが分かると思います。
画像にもアンチエイリアスを掛けられます。中央のカップケーキが原寸大、右下がアンチエイリアスなし、左下がアンチエイリアスありです。それぞれ4倍に拡大しています。
Javaでjava.awt.Graphicsクラスを扱ったことがあるなら、ダブルバッファリングの重要性はご存じかと思います。
ダブルバッファリングを行わないと、描画時に画面がちらついてしまいます。このテクニックは、Java AppletのころからJava SEでもJava MEでも必須でしたが、Androidではフレームワークが内部でダブルバッファリングを行ってくれるため、オフスクリーンバッファを持たなくてもよくなりました。
勘の良い方は気が付いているかもしれませんが、SurfaceHolderのlockCanvas()メソッドはスレッドセーフに作られています。要するに、ほかのスレッドでlockCanvas()が呼ばれると、もう一方のスレッドは、unlockCanvasAndPost(Canvas)が呼び出されるまで描画を行えません。その待っている間にオフスクリーンに描画を済ませてしまう、というのはテクニックの1つです。
また、iアプリやMIDPからアプリを移植する際には、オフスクリーンを持つ構造にしておくと、移植の際の手間やバグが減るでしょう。iアプリやMIDPについては、下記記事と連載をご参照ください。
次ページでは、UIイベントを駆使した描画と背景を透過させる方法について解説します。
Copyright © ITmedia, Inc. All Rights Reserved.