を使って描画した図形とButtonなどを同じレイアウトに入れたい。そんな時はRelativeLayout等のレイアウトとCanvasを重ねると可能です
 
![[Android] Custom Canvas をレイアウトに挿入する 1x1.trans - [Android] Custom Canvas をレイアウトに挿入する](https://akira-watson.com/wp-content/themes/simplicity2/images/1x1.trans.gif)
2024.1.1
CustomとLayout
Canvasで描画していて困るのは、テキストやボタンなどと一緒にスクリーン上に表示したいというリクエストです。タッチリスナーや色々と手を尽くせば可能ですがコードが煩雑になりメンテしにくくなります。
 
そんな時は、Canvasで作成した描画領域、ViewをあたかもTextViewなどのようにレイアウトに張り付けることで解決できます。
 
ViewをLayoutに入れる
Buttonなどのように扱うために「パッケージ名+Viewのクラス名」で定義します。
例えば、com.example.testcanvasinsertion がパッケージ名で
MyViewがクラス名であれば
 
| 1 2 3 4 | <com.example.testcanvasinsertion.MyView         android:layout_width="wrap_content"         android:layout_height="wrap_content"         ... /> | 
 
これで、下のようにButtonやTextViewと同じように扱えます。
 
| 1 2 3 4 5 6 7 8 | <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout      ...      <com.example.testcanvasinsertion.MyView         ... />     ...   </androidx.constraintlayout.widget.ConstraintLayout > | 
サンプルコード
テキストとボタンのレイアウトに Canvas の描画領域を挿入して(重ねて)みたいと思います。
MyViewクラスを新たに作成します。
 
MyView.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 | //package com.example.testcanvasinsertion; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.view.View; public class MyView extends View {     Paint paint;     public MyView(Context context, AttributeSet attrs) {         super(context, attrs);         paint = new Paint();     }     @Override     protected void onDraw(Canvas canvas) {         // 背景、半透明         canvas.drawColor(Color.argb(127, 0, 127, 63));         // 円         paint.setColor(Color.argb(255, 68, 255, 255));         paint.setStrokeWidth(30);         paint.setAntiAlias(true);         paint.setStyle(Paint.Style.STROKE);         // (x1,y1,r,paint) 中心x1座標, 中心y1座標, r半径         canvas.drawCircle(450, 450, 100, paint);         // 矩形         paint.setColor(Color.argb(255, 255, 190, 0));         paint.setStrokeWidth(10);         paint.setStyle(Paint.Style.STROKE);         // (x1,y1,x2,y2,paint) 左上の座標(x1,y1), 右下の座標(x2,y2)         canvas.drawRect(480, 480, 850, 880, paint);         // 線         paint.setStrokeWidth(15);         paint.setColor(Color.argb(255, 0, 255, 120));         // (x1,y1,x2,y2,paint) 始点の座標(x1,y1), 終点の座標(x2,y2)         canvas.drawLine(350, 850, 750, 630, paint);     } } | 
 
次にMainActivityを作ります。
 
MainActivity.java
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | //package com.example.testcanvasinsertion; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.widget.TextView; public class MainActivity extends AppCompatActivity {     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);         TextView label = this.findViewById(R.id.label);         label.setText(R.string.text);     } } | 
 
activity_main.xmlのレイアウトファイルに
com.example.testcanvasinsertion.MyView
のタグで記述します
activity_main.xml
| 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 | <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout     xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:app="http://schemas.android.com/apk/res-auto"     xmlns:tools="http://schemas.android.com/tools"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:background="#000"     tools:context=".MainActivity">     <!-- ここは自分のプロジェクトに合わせる -->     <com.example.testcanvasinsertion.MyView         android:layout_width="340dp"         android:layout_height="420dp"         app:layout_constraintBottom_toBottomOf="parent"         app:layout_constraintLeft_toLeftOf="parent"         app:layout_constraintRight_toRightOf="parent"         app:layout_constraintTop_toTopOf="parent" />     <TextView         android:id="@+id/label"         android:textSize="20sp"         android:textColor="#cccccc"         android:layout_marginStart="100dp"         android:layout_marginEnd="60dp"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         app:layout_constraintBottom_toBottomOf="parent"         app:layout_constraintLeft_toLeftOf="parent"         app:layout_constraintRight_toRightOf="parent"         app:layout_constraintTop_toTopOf="parent"         app:layout_constraintVertical_bias="0.2" />     <Button         android:text="@string/button"         android:layout_width="200dp"         android:layout_height="wrap_content"         app:layout_constraintBottom_toBottomOf="parent"         app:layout_constraintLeft_toLeftOf="parent"         app:layout_constraintRight_toRightOf="parent"         app:layout_constraintTop_toTopOf="parent"         app:layout_constraintVertical_bias="0.88" /> </androidx.constraintlayout.widget.ConstraintLayout> | 
 
stringのリソースです
strings.xml
| 1 2 3 4 5 6 7 | <resources>     <string name="app_name">TestCanvasInsertion</string>     <string name="button">Button</string>     <string name="text">"abcd123456789cdefg\n1234567893456978         \nhijklmnopq012698745rst4565848uvwxlmnopqffsjldalkdfasdfks         \n\n\n\n\n\n012698745rst4565848asdf\nuvwx"</string> </resources> | 
 
![[Android] Custom Canvas をレイアウトに挿入する 1x1.trans - [Android] Custom Canvas をレイアウトに挿入する](https://akira-watson.com/wp-content/themes/simplicity2/images/1x1.trans.gif)
Canvasエリアは描画領域がわかりやすいように半透明の矩形を使いました。
- 関連ページ
- Canvas と Paint で円や矩形を描く
- Custom Canvas をレイアウトに挿入する
- Canvas を Clear して再描画
- Canvas で画像と文字を表示する
- Canvas Animation で円弧を動かす
 
References:
Canvas | Android Developers
Canvas and Drawables | Android Developers
