前のページで Canvas で描画した領域を消したり表示したりする場合にPorterDuff.Mode.CLEARを使いましたが、部分的に表示・非表示をしたい場合にはちょっと使いにくいかもしれません。
それぞれが重なっていると、重なった部分が黒抜きで消えたり色々面倒です。シンプルに全て再描画を使う方がいいかもしれません。
。
2024.1.1
Canvasに画像とテキストを表示
この例では、TextViewでのテキストとCanvas上のテキストが混在します。またCanvas領域に画像を表示していますが、これもImageViewで表示することもできます
drawBitmap、drawText
Canvasに画像とテキストを描画するのに、drawBitmapを使います
drawBitmapは色々使い方がありますが、簡単なところでは、
1 2 3 4 |
public void drawBitmap (Bitmap bitmap, float left, float top, Paint paint) |
画像をdrawableに入れて、CanvasのためのViewを継承したクラスを作成して
画像の描画をしてみます
leftはxポジション、topはyポジションとして
1 2 3 4 5 6 7 8 9 10 |
// 画像をresource drawableからBitmapとして呼び出し Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.image); ... @Override protected void onDraw(Canvas canvas) { ... // drawBitmapを使って描画 canvas.drawBitmap(bmp, x, y, paint); ... } |
文字列の表示の場合は、drawTextを使います
1 2 3 4 |
public void drawText (String text, float x, float y, Paint paint) |
文字列を表示するには、描画スタイルの設定をします
Paint.Style.FILL_AND_STROKE
1 2 3 4 5 6 7 8 9 10 |
... @Override protected void onDraw(Canvas canvas) { ... // StyleをFILL_AND_STROKEに変更 Paint.Style.FILL_AND_STROKE // drawTextで文字列を表示 canvas.drawText("Text", x, y, paint) ... } |
サンプルコード
button によりCanvas領域での画像と文字を切り替えます。
画像 img.jpg など適宜drawableに入れておきます。
まずCanvasを作るためにTestCanvasViewクラスを新しく作成
この例の package は 「com.example.testcanvasimagetext」で設定しました
TestCanvasView.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 |
//package com.example.testcanvasimagetext; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.view.View; public class TestCanvasView extends View { private final Paint paint; private Boolean viewflg; private final Bitmap bmp; public TestCanvasView(Context context, AttributeSet attrs) { super(context, attrs); paint = new Paint(); viewflg = true; bmp = BitmapFactory.decodeResource(getResources(), R.drawable.umbrella); } public void showCanvas(boolean flg){ viewflg = flg; invalidate(); } @Override protected void onDraw(Canvas canvas) { String str = "京和傘"; // 背景、半透明 canvas.drawColor(Color.argb(125, 0, 0, 255)); // Bitmap 画像を表示 if(viewflg){ canvas.drawBitmap(bmp, 80, 200, paint); } // Textの表示 else{ paint.setStyle(Paint.Style.FILL_AND_STROKE); paint.setStrokeWidth(5); paint.setTextSize(100); paint.setColor(Color.argb(255, 255, 255, 0)); canvas.drawText(str, 300, 600, paint); } // 円 paint.setColor(Color.argb(255, 255, 0, 255)); paint.setStrokeWidth(30); paint.setAntiAlias(true); paint.setStyle(Paint.Style.STROKE); // (x1,y1,r,paint) 中心x1座標, 中心y1座標, r半径 canvas.drawCircle(130, 150, 100, paint); paint.setStrokeWidth(30); paint.setAntiAlias(true); paint.setStyle(Paint.Style.STROKE); // (x1,y1,r,paint) 中心x1座標, 中心y1座標, r半径 canvas.drawCircle(130, 150, 50, paint); } } |
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 |
//package com.example.testcanvasimagetext; import android.os.Bundle; import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; import android.widget.Button; import android.widget.TextView; public class MainActivity extends AppCompatActivity { private boolean showCanvas; private TestCanvasView testCanvasView; @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; }); TextView label = this.findViewById(R.id.label); label.setText(getString(R.string.text)); testCanvasView = this.findViewById(R.id.test_view); testCanvasView.showCanvas(true); showCanvas = true; Button button = findViewById(R.id.button); button.setOnClickListener(v -> { if (showCanvas) { testCanvasView.showCanvas(false); showCanvas = false; } else { testCanvasView.showCanvas(true); showCanvas = true; } }); } } |
レイアウトの中にカスタムで作成したCanvasを挿入する形にします。
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:id="@+id/main" android:background="#000" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <!-- projectのpackagename+canvasにクラス --> <com.example.testcanvasimagetext.TestCanvasView android:id="@+id/test_view" android:layout_width="340dp" android:layout_height="420dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/label" android:textSize="11sp" android:textColor="#ccc" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintVertical_bias="0.15" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/button" android:text="@string/button" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintVertical_bias="0.85" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> |
strings.xml
1 2 3 4 5 |
<resources> <string name="app_name">TestCanvasImageText</string> <string name="button">Button</string> <string name="text">"Test Canvas\nBitMap amp Text"</string> </resources> |
ボタンをタップすると
関連ページ:
- Canvas と Paint で円や矩形を描く
- Custom Canvas をレイアウトに挿入する
- Canvas を Clear して再描画
- Canvas で画像とテキストを表示する
- Canvas Animation で円弧を動かす
References:
Canvas | Android Developers
Canvas and Drawables | Android Developers
Canvas drawBitmap