Canvas で描画した領域を動的に非表示にしたり表示したりする場合には、canvas.drawColor(0, PorterDuff.Mode.CLEAR) を使います。また同時に、クリアした後で再描画しますがそれには invalidate() を使います。
2024.1.1
Canvasの再描画
TextViewなどは表示、非表示ができますがCanvasの場合はどうでしょう
Cavasの場合は一旦クリアーして、その後再描画が必要です。次に表示させる時にもまた再描画が必要です
最初に簡単のためボタンで表示・非表示を実装してみたいと思います
invalidate()
描画をクリアーするには、
canvas.drawColor(0, PorterDuff.Mode.CLEAR)
を使います。
また再描画のためにはinvalidate()を使います。Canvasをクリアしてから描画です。
ただし、invalidate()は再描画させるためにonDraw()を呼び出しますが、即呼び出されるわけではなく、都合がつくまで待たされるようです。ですから、即非表示を想定する場合はHandlerを使う方法が必要になります。
以前にCanvasを作成した方法 と同様に作成します。
例として package は 「package com.example.testcanvasclear」 で設定しました。
button によりフラグを切り替え
canvas.drawColor(0, PorterDuff.Mode.CLEAR);
を実行して
invalidate();
で再描画します
サンプルコード
新しく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 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 |
package com.example.testcanvasclear; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PorterDuff; import android.util.AttributeSet; import android.util.Log; import android.view.View; public class MyView extends View { private final Paint paint = new Paint(); private final Path path = new Path(); private Boolean viewflg; public MyView(Context context, AttributeSet attrs) { super(context, attrs); viewflg = true; } public void showCanvas(boolean flg){ viewflg = flg; // 再描画 invalidate(); } @Override protected void onDraw(Canvas canvas) { Log.d("TestView", " onDraw()"); if(viewflg){ Log.d("TestView", " viewflg = true"); // 背景、半透明 canvas.drawColor(Color.argb(125, 0, 0, 255)); // 円 paint.setColor(Color.argb(255, 68, 125, 255)); paint.setStrokeWidth(30); paint.setAntiAlias(true); paint.setStyle(Paint.Style.STROKE); // (x1,y1,r,paint) 中心x1座標, 中心y1座標, r半径 canvas.drawCircle(450, 450, 300, paint); // 矩形 paint.setColor(Color.argb(255, 255, 0, 255)); paint.setStrokeWidth(10); paint.setStyle(Paint.Style.STROKE); // (x1,y1,x2,y2,paint) 左上の座標(x1,y1), 右下の座標(x2,y2) canvas.drawRect(480, 480, 850, 880, paint); // 三角形を書く float tx1 = 500; float ty1 = 420; float tx2 = 200; float ty2 = 800; float tx3 = 700; float ty3 = 800; paint.setStrokeWidth(10); paint.setColor(Color.YELLOW); path.moveTo(tx1, ty1); path.lineTo(tx2, ty2); path.lineTo(tx3, ty3); path.lineTo(tx1, ty1); canvas.drawPath(path, paint); } else{ Log.d("TestView", " viewflg = false"); // 描画クリア canvas.drawColor(0, PorterDuff.Mode.CLEAR); } } } |
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 |
package com.example.testcanvasclear; 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.util.Log; import android.widget.Button; import android.widget.TextView; public class MainActivity extends AppCompatActivity { private boolean showCanvas; private MyView myView; @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(R.string.text); Log.d("MainActivity", "onCreate()"); myView = this.findViewById(R.id.my_view); myView.showCanvas(true); showCanvas = true; Button button = findViewById(R.id.button); button.setOnClickListener(v -> { Log.d("debug","button on click"); if (showCanvas) { myView.showCanvas(false); showCanvas = false; Log.d("debug"," showCanvas = false"); } else { myView.showCanvas(true); showCanvas = true; Log.d("debug"," showCanvas = true"); } }); } } |
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 45 46 47 48 49 |
<?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:layout_width="match_parent" android:layout_height="match_parent" android:background="#000" tools:context=".MainActivity"> <!-- package name に合わせる --> <com.example.testcanvasclear.MyView android:id="@+id/my_view" 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:id="@+id/button" android:text="@string/button" android:layout_alignParentBottom="true" android:layout_margin="120dp" 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.88" /> </androidx.constraintlayout.widget.ConstraintLayout> |
Stringのリソース
strings.xml
1 2 3 4 5 6 7 |
<resources> <string name="app_name">TestCanvasClear</string> <string name="button">Button</string> <string name="text">"abcd123456789cdefg\n1234567893456978 \nhijklmnopq012698745rst4565848uvwxlmnopq \n\n\n\n012698745rst4565848\nuvwx"</string> </resources> |
ボタンタップすると
古い動画です
マニュアルで表示・非表示ができました
References:
Canvas | Android Developers
Canvas and Drawables | Android Developers