図形を描画するために Canvas と Paint クラスがあります。Canvas は絵を描くカンバスです、円や矩形などの図形をこれで設定します。
2024.1.1
Canvas
さてCanvasとは何でしょうか?GoogleはAndroidフレームワークとしてグラフィックスにおいては2つの方法を提供しています。
- Drawables
- 画像などをViewを使って表示。静的で表示させるだけの用途であり、アニメーションでも決まりきった動きのものに適している
パフォーマンスを必要とするようなゲームにはあまり向かない - 代表的な例は、画像をresourceのdrawableにおいてImageViewを使って表示するような例。
- 画像などをViewを使って表示。静的で表示させるだけの用途であり、アニメーションでも決まりきった動きのものに適している
- Canvas
- onDrawメソッドを使ってCanvas上で描画。ゲームなどの動きがありグラフィックスのredrawが頻繁に起きる場合や、カスタマイズされたアニメーションに向いている
Ref: Canvas and Drawables
ゲームのようなものでなければDrawablesを使えばそこそこできますが、どうしてもカスタム化して動きを入れたいというような場合ではCavasを使います。
Canvasの基本的な形
Canvasでprimitiveな矩形を描画する基本的な例です。
Activity から View を継承したクラスを作りsetContentViewに入れてonDraw() で描画します。setContentView(MyView)
レイアウトファイルは使いません。
MainActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
//package com.example.testcanvas; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.view.View; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // EdgeToEdge.enable(this); // setContentView(R.layout.activity_main); // ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { // Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); // v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); // return insets; // }); MyView myView = new MyView(this); setContentView(myView); } // Viewを継承したクラス static class MyView extends View { Paint paint; // 描画するラインの太さ float StrokeWidth = 20.0f; public MyView(Context context) { super(context); paint = new Paint(); } @Override protected void onDraw(Canvas canvas) { // ペイントする色の設定 paint.setColor(Color.argb(255, 255, 0, 255)); // ペイントストロークの太さを設定 paint.setStrokeWidth(StrokeWidth); // Styleのストロークを設定する paint.setStyle(Paint.Style.STROKE); // drawRectを使って矩形を描画する、引数に座標を設定 // (x1,y1,x2,y2,paint) 左上の座標(x1,y1), 右下の座標(x2,y2) canvas.drawRect(300, 300,600, 600, paint); } } } |
矩形が描画されました。
矩形の描画では
Paint クラスの
setColor で線の色を指定
setStrokeWidth にて線の太さ
Canvas クラスの
drawRect を使って4つの頂点を引数に入れます。
サンプルコード
矩形以外にも円、楕円のような基本的なprimitiveな図形を描画するメソッドもあります。またラインを組み合わせて三角形を作ることもできます。
MainActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
package com.example.testcanvas; import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.view.View; import android.graphics.Path; import android.util.Log; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // EdgeToEdge.enable(this); // setContentView(R.layout.activity_main); // ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { // Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); // v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); // return insets; // }); MyView myView = new MyView(this); setContentView(myView); } static class MyView extends View { Paint paint; Path path; float StrokeWidth1 = 20f; float StrokeWidth2 = 40f; float dp; public MyView(Context context) { super(context); paint = new Paint(); path = new Path(); dp = getResources().getDisplayMetrics().density; Log.d("debug","fdp="+dp); } @Override protected void onDraw(Canvas canvas) { // 背景 canvas.drawColor(Color.argb(255, 0, 0, 125)); // Canvas 中心点 float xc = (float)getWidth()/2; float yc = (float)getHeight()/2; // 円 paint.setColor(Color.argb(255, 125, 125, 255)); paint.setStrokeWidth(StrokeWidth1); paint.setAntiAlias(true); paint.setStyle(Paint.Style.STROKE); // (x1,y1,r,paint) 中心x1座標, 中心y1座標, r半径 canvas.drawCircle(xc - 15*dp, yc - 55*dp, xc / 2, paint); // 矩形 paint.setColor(Color.argb(255, 255, 0, 255)); paint.setStyle(Paint.Style.STROKE); // (x1,y1,x2,y2,paint) 左上の座標(x1,y1), 右下の座標(x2,y2) canvas.drawRect(xc - 30*dp, yc - 50*dp, xc + 120*dp, yc + 100*dp, paint); // 線 paint.setStrokeWidth(StrokeWidth1); paint.setColor(Color.argb(255, 0, 255, 0)); // (x1,y1,x2,y2,paint) 始点の座標(x1,y1), 終点の座標(x2,y2) canvas.drawLine(xc + 20*dp, yc - 30*dp, xc - 70*dp, yc + 70*dp, paint); // 三角形を書く float tx1 = 230*dp; float ty1 = 370*dp; float tx2 = 100*dp; float ty2 = 500*dp; float tx3 = 350*dp; float ty3 = 500*dp; paint.setStrokeWidth(10); paint.setColor(Color.WHITE); path.moveTo(tx1, ty1); path.lineTo(tx2, ty2); path.lineTo(tx3, ty3); path.lineTo(tx1, ty1); canvas.drawPath(path, paint); // 円 paint.setColor(Color.YELLOW); paint.setStrokeWidth(StrokeWidth2); paint.setAntiAlias(true); paint.setStyle(Paint.Style.STROKE); // (x,y,r,paint) x座標, y座標, r半径 canvas.drawCircle(220*dp, 130*dp, 40*dp, paint); } } } |
ここで指定している(x,y)はピクセルになりますので端末依存です。スクリーン縦横のサイズを取得して計算する必要があります。
Kotlinで書くと
https://akira-watson.com/android/kotlin/canvas.html
- 関連ページ
- Canvas と Paint で円や矩形を描く
- Custom Canvas をレイアウトに挿入する
- Canvas を Clear して再描画
- Canvas で画像と文字を表示する
- Canvas Animation で円弧を動かす
References:
Canvas | Android Developers
Canvas and Drawables | Android Developers