画面に図形を描画するコードを紹介します。
プロジェクトの作成
Android アプリケーションプロジェクトを作成します。
[New Android Application]ダイアログボックスが表示されますので、以下を設定します。
- Application Name: "CanvasDraw"
- Project Name: "CanvasDraw"
- Package Name: "com.iPentec.canvasdraw"
- Minimum Required SDK: "API 8: Android 2.2 (Froyo)"
- Target SDK: "API 17: Android 4.2 (Jelly Bean)"
- Compile With: "API 17: Android 4.2 (Jelly Bean)"
- Theme: "Holo Light with Dark Action Bar"
ビューの追加
画面に図形を描画する場合はカスタム化したViewクラスを用います。ビューの追加手順を紹介します。
"Package Explorer"のプロジェクトのノードを選択し右クリックします。[New]メニューの[Other]メニューを選択します。
[New]ダイアログが表示されます。一覧から[Android]カテゴリの[Android Object]を選択します。選択後[Next]ボタンを押します。
[New Android Object]ダイアログが表示されます。一覧から"Custom View"を選択し、[Next]ボタンを押します。
カスタムビューのクラス名を設定します。今回は"MyView"としました。設定ができたら[Next]ボタンを押します。
プレビュー画面が表示され、コードの変更部分などが確認できます。[Finish]ボタンを押してカスタムビューの追加を完了します。
コード
UIをデザインする前にカスタムビューを含むコードを記述します。
MainActivity.java
package com.iPentec.canvasdraw;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@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;
}
}
MyView.java
package com.iPentec.canvasdraw;
import java.util.Random;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;
/**
* TODO: document your custom view class.
*/
public class MyView extends View {
private String mExampleString; // TODO: use a default from R.string...
private int mExampleColor = Color.RED; // TODO: use a default from R.color...
private float mExampleDimension = 0; // TODO: use a default from R.dimen...
private Drawable mExampleDrawable;
private TextPaint mTextPaint;
private float mTextWidth;
private float mTextHeight;
public MyView(Context context) {
super(context);
init(null, 0);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs, 0);
}
public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs, defStyle);
}
private void init(AttributeSet attrs, int defStyle) {
// Load attributes
}
private void invalidateTextPaintAndMeasurements() {
mTextPaint.setTextSize(mExampleDimension);
mTextPaint.setColor(mExampleColor);
mTextWidth = mTextPaint.measureText(mExampleString);
Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
mTextHeight = fontMetrics.bottom;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// TODO: consider storing these as member variables to reduce
// allocations per draw cycle.
int paddingLeft = getPaddingLeft();
int paddingTop = getPaddingTop();
int paddingRight = getPaddingRight();
int paddingBottom = getPaddingBottom();
int contentWidth = getWidth() - paddingLeft - paddingRight;
int contentHeight = getHeight() - paddingTop - paddingBottom;
Rect r = new Rect(0,0,canvas.getWidth(), canvas.getHeight());
Paint p = new Paint();
p.setColor(Color.argb(255, 0, 0, 0));
canvas.drawRect(r, p);
}
/**
* Gets the example string attribute value.
*
* @return The example string attribute value.
*/
public String getExampleString() {
return mExampleString;
}
/**
* Sets the view's example string attribute value. In the example view, this
* string is the text to draw.
*
* @param exampleString
* The example string attribute value to use.
*/
public void setExampleString(String exampleString) {
mExampleString = exampleString;
invalidateTextPaintAndMeasurements();
}
/**
* Gets the example color attribute value.
*
* @return The example color attribute value.
*/
public int getExampleColor() {
return mExampleColor;
}
/**
* Sets the view's example color attribute value. In the example view, this
* color is the font color.
*
* @param exampleColor
* The example color attribute value to use.
*/
public void setExampleColor(int exampleColor) {
mExampleColor = exampleColor;
invalidateTextPaintAndMeasurements();
}
/**
* Gets the example dimension attribute value.
*
* @return The example dimension attribute value.
*/
public float getExampleDimension() {
return mExampleDimension;
}
/**
* Sets the view's example dimension attribute value. In the example view,
* this dimension is the font size.
*
* @param exampleDimension
* The example dimension attribute value to use.
*/
public void setExampleDimension(float exampleDimension) {
mExampleDimension = exampleDimension;
invalidateTextPaintAndMeasurements();
}
/**
* Gets the example drawable attribute value.
*
* @return The example drawable attribute value.
*/
public Drawable getExampleDrawable() {
return mExampleDrawable;
}
/**
* Sets the view's example drawable attribute value. In the example view, this
* drawable is drawn above the text.
*
* @param exampleDrawable
* The example drawable attribute value to use.
*/
public void setExampleDrawable(Drawable exampleDrawable) {
mExampleDrawable = exampleDrawable;
}
}
解説
MainActivity.javaは修正はしません。
MyView.javaはonDraw()メソッド内にコードを記述します。
OnDraw() メソッド
下記のOnDrawメソッドが画面の更新時に実行されるメソッドです。このメソッド内に画面描画処理を記述します。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// TODO: consider storing these as member variables to reduce
// allocations per draw cycle.
int paddingLeft = getPaddingLeft();
int paddingTop = getPaddingTop();
int paddingRight = getPaddingRight();
int paddingBottom = getPaddingBottom();
int contentWidth = getWidth() - paddingLeft - paddingRight;
int contentHeight = getHeight() - paddingTop - paddingBottom;
Rect r = new Rect(0,0,canvas.getWidth(), canvas.getHeight());
Paint p = new Paint();
p.setColor(Color.argb(255, 0, 0, 0));
canvas.drawRect(r, p);
}
int paddingLeft = getPaddingLeft();
int paddingTop = getPaddingTop();
int paddingRight = getPaddingRight();
int paddingBottom = getPaddingBottom();
int contentWidth = getWidth() - paddingLeft - paddingRight;
int contentHeight = getHeight() - paddingTop - paddingBottom;
上記の6行は画面の描画領域の寸法を取得するコードです。今回は利用しません。
Rect r = new Rect(0,0,canvas.getWidth(), canvas.getHeight());
画面を塗りつぶすための矩形を作成します。canvas.getWidth(), canvas.getHeight()メソッドを呼び出すことでキャンバスの幅と高さを取得できます。上記のコードでは画面全体囲む矩形を作成しています。
Paint p = new Paint();
画面を塗りつぶすためのペンを準備します。
p.setColor(Color.argb(255, 0, 0, 0));
先の行で準備したペンに色を設定指定します。Color.argbに与えている引数は、第一引数から、透明度、R成分、G成分、B成分となっています。今回、不透明の黒で塗りつぶすので透明度は255にします。他の引数は0にします。
canvas.drawRect(r, p);
画面に矩形を描画します。第一引数に塗りつぶす矩形のRectオブジェクトを、第二引数に描画に使うペンオブジェクトを与えます。
UI
UIを作成します。MainActivityのレイアウトファイルを開きます。下図のデザイナ画面が表示されます。
デザイナ画面の左側の[Palette]の"Custom & Library Views"カテゴリを選択します。一覧に[MyView]コントロールが追加されていますので、これをフォームにドラッグ&ドロップします。
ドロップできるとフォームにMyViewが配置できます。
実行結果
上記のプロジェクトを実行すると下図の画面が表示されます。MyViewのコントロール内部が黒で塗りつぶされました。
パラメータの変更
onDrawメソッドを下記に変更します。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Rect r = new Rect(0,0,canvas.getWidth(), canvas.getHeight());
Paint p = new Paint();
p.setColor(Color.argb(255, 0, 128, 0));
canvas.drawRect(r, p);
}
実行すると下図の結果となります。G成分を128にしたので緑色で塗りつぶされました。
描画する図形を増やす
onDrawメソッドを下記に変更します。
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// TODO: consider storing these as member variables to reduce
// allocations per draw cycle.
int paddingLeft = getPaddingLeft();
int paddingTop = getPaddingTop();
int paddingRight = getPaddingRight();
int paddingBottom = getPaddingBottom();
int contentWidth = getWidth() - paddingLeft - paddingRight;
int contentHeight = getHeight() - paddingTop - paddingBottom;
Rect r = new Rect(0,0,canvas.getWidth(), canvas.getHeight());
Paint p = new Paint();
p.setColor(Color.argb(255, 0, 0, 0));
canvas.drawRect(r, p);
Rect rs = new Rect(200,200,200+32,200+32);
Paint ps = new Paint();
ps.setColor(Color.argb(255, 160, 160, 255));
canvas.drawRect(rs, ps);
}
Rect rs = new Rect(200,200,200+32,200+32);
Paint ps = new Paint();
ps.setColor(Color.argb(255, 160, 160, 255));
canvas.drawRect(rs, ps);
を追加しました。(x,y)=(200,200)の位置に幅32、高さ32の矩形を描画します。カラーは(R,G,B)=(160,160,255)です。
プロジェクトを実行すると下図の結果となります。
描画する図形を増やす2
図形が一つだけでは寂しいので、乱数を用いて矩形を64個描画させるコードが下記です。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// TODO: consider storing these as member variables to reduce
// allocations per draw cycle.
int paddingLeft = getPaddingLeft();
int paddingTop = getPaddingTop();
int paddingRight = getPaddingRight();
int paddingBottom = getPaddingBottom();
int contentWidth = getWidth() - paddingLeft - paddingRight;
int contentHeight = getHeight() - paddingTop - paddingBottom;
Rect r = new Rect(0,0,canvas.getWidth(), canvas.getHeight());
Paint p = new Paint();
p.setColor(Color.argb(255, 0, 0, 0));
canvas.drawRect(r, p);
//
Random rnd = new Random();
for (int i=0;i<64; i++){
int rx = rnd.nextInt(canvas.getWidth());
int ry = rnd.nextInt(canvas.getHeight());
int rr = rnd.nextInt(255);
int rg = rnd.nextInt(255);
int rb = rnd.nextInt(255);
Rect rs = new Rect(rx,ry,rx+32,ry+32);
Paint ps = new Paint();
ps.setColor(Color.argb(255, rr, rg, rb));
canvas.drawRect(rs, ps);
}
}
実行すると下図の結果となります。
著者
iPentecのプログラマー、最近はAIの積極的な活用にも取り組み中。
とっても恥ずかしがり。
最終更新日: 2024-01-04
作成日: 2013-03-08