Paint は、Android Canvas でグラフィックをスタイリングするための主要クラスです。色、線の太さ、塗りつぶしスタイル、ぼかし効果、フォントを、ユーザーインターフェースのすべての描画操作に対して定義します。Paint がないと、Canvas は表示要素に視覚属性を適用できません。Google Developers, 2026 によると、Paint はグラデーションやテクスチャを含めて最大42個のスタイルパラメータをサポートします。
要点
Paint は、Canvas での描画操作のすべてのスタイル設定を保持する android.graphics パッケージのクラスです。ピクセル自体は含まれず、線、図形、テキストがどのように見えるかを定義します。Canvas メソッドの各呼び出し — drawCircle、drawLine、drawText — は視覚表現の解釈に Paint を使用します。
Paint は設定オブジェクトの原理で動作します。インスタンスを作成し、パラメータを一度設定して、複数の操作で再利用します。これにより描画ループ内の割り当て回数が最小限になり、毎フレーム新しいオブジェクトを作成する場合と比べてパフォーマンスが最大30%向上します。Google I/O 2024 によると、Paint の最適化はカスタムグラフィックスで 60 FPS を達成するための重要なプラクティスの1つです。
Paint のすべての設定は複数のカテゴリに分けられます: 色と透明度、ストロークと塗りつぶしスタイル、テキストとフォントの処理、ぼかしとマスキング効果。各カテゴリは個別のセッターメソッドで制御され、任意の組み合わせで利用できます。これにより Paint API は柔軟ですが、パラメータ間の相互作用を理解する必要があります — たとえば Style は Shader が輪郭に適用されるか塗りつぶしに適用されるかに影響します。
setColor は、後続のすべての描画操作の色を設定する主要メソッドです。色は ARGB 形式 (32ビット整数) で渡され、上位8ビットがアルファチャネル、残りが赤、緑、青のチャネルです。値 0xFF0000FF は不透明な青色を設定します。
setAlpha メソッドは、0 (完全に透明) から 255 (完全に不透明) の範囲で透明度を独立して調整できます。setColor でアルファを指定するのとは異なり、このメソッドは既に設定された色相に影響しません — 全体的な透明度だけを調整します。これは色を変えずに要素の表示・非表示をアニメーションするのに便利です。
ColorFilter は描画前に各ピクセルの色を変換する仕組みです。3つのモードがサポートされます: チャネルの乗算と加算を行う LightingColorFilter、ブレンドモードを使う PorterDuffColorFilter、完全なマトリックス変換を行う ColorMatrixColorFilter。ColorFilter は Shader の後、Canvas への出力の前に適用されます。
ほとんどのタスクでは標準の setColor または setAlpha で十分です。ColorFilter は主に脱色、セピア、反転の効果に使用されます。ColorFilter の適用は GPU の負荷を増やすため、Google は onDraw のループ呼び出しでの使用を最小限にすることを推奨しています。
| メソッド | 説明 | パフォーマンス |
|---|---|---|
| setColor | ARGB で色を設定 | O(1) — オーバーヘッドなし |
| setAlpha | 透明度 (0-255) を調整 | O(1) — 軽量な操作 |
| setColorFilter | 色補正を適用 | O(n) — 頻繁な呼び出しで FPS に影響 |
setStyle メソッドは Paint.Style の3つの値のいずれかを受け取ります: FILL (塗りつぶし)、STROKE (輪郭)、または FILL_AND_STROKE (両方同時)。スタイルの選択によって、図形がシルエット、骨組み、または内部塗りつぶし付きの輪郭として表示されるかが決まります。デフォルトでは Paint は FILL スタイルで作成されます。
setStrokeWidth は STROKE モードの線の太さをピクセル単位で設定します。丸い図形や角の丸みには setStrokeCap (Cap.ROUND、BUTT、SQUARE) と setStrokeJoin (Join.MITER、ROUND、BEVEL) が使われます。これらのパラメータはカスタム View のグラフ、パス、フレームの外観に大きな影響を与えます。
1ピクセル未満の太さでは線はサブピクセル精度で描画されますが、低密度の画面ではぼやけて見えることがあります。Android の Retina ディスプレイでは、dp をピクセルに変換するために TypedValue.applyDimension を使用してください。2 dp の太さはほとんどのデバイスで鮮明な視認性を保証します。
DashPathEffect は点線や一点鎖線を作成します。コンストラクタは交互のダッシュとギャップの長さの配列と初期フェーズオフセットを受け取ります。たとえば配列 [10, 5, 3, 5] は長いダッシュ、短いギャップ、短いダッシュ、ギャップの線を作成します。この効果はグラフィックエディタや注釈ツールでよく使われます。
スタイルの組み合わせは setPathEffect で行います。CornerPathEffect、DashPathEffect、DiscretePathEffect を組み合わせると、図表、ラベル、装飾要素用の複雑な視覚線を作成できます。各 PathEffect は CPU で計算されるため、多くの線を含むアニメーションでは効果を事前に Bitmap にラスタライズすることをお勧めします。
val paint = Paint().apply {
setStyle(Paint.Style.STROKE)
setStrokeWidth(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2f, resources.displayMetrics))
setPathEffect(DashPathEffect(floatArrayOf(10f, 5f, 3f, 5f), 0f))
}
Typeface は、Paint のすべてのテキスト操作の書体を定義するオブジェクトです。Android はシステムフォント (Roboto、Noto Sans)、assets リソースのカスタムフォント、Downloadable Fonts API で読み込むフォントをサポートします。Typeface の設定は Paint インスタンスの setTypeface で行います。
setTextSize メソッドはフォントサイズをピクセル単位で設定します。異なる画面で正しく表示するには、TypedValue.applyDimension を使って sp 単位でサイズを指定することをお勧めします。行間は水平方向の引き伸ばし用の setTextScaleX で調整され、Canvas.drawText による複数行テキストの組み込みサポートに含まれます。
テキストの配置には setTextAlign が LEFT、CENTER、RIGHT の値で使用されます。CENTER では drawText に渡された x 座標がテキストの中心点になります — これはアイコンの下のラベルや図形内のタイトルに特に便利です。正確な配置には measureText と getTextBounds メソッドが使われ、テキストの幅と境界矩形を返します。
setUnderlineText と setStrikeThruText はそれぞれ下線と取り消し線を有効にします。これらのパラメータは書体レベルで機能し、この Paint で描画されるすべてのテキストに適用されます。1つの文字列の異なる部分を柔軟にフォーマットするには、設定の異なる別々の Paint オブジェクトを使うか、drawText 呼び出しの間でパラメータを切り替えてください。
| メソッド | 目的 | 単位 |
|---|---|---|
| setTextSize | フォントサイズ | px (ピクセル) |
| setTextAlign | 水平配置 | LEFT、CENTER、RIGHT |
| setTypeface | 書体 | Typeface object |
| setUnderlineText | 下線 | Boolean |
Shader は図形をグラデーション、ラスターテクスチャ、コンポジティングで塗りつぶすための基本クラスです。setShader メソッドでサブクラスのいずれかを設定できます: LinearGradient、RadialGradient、SweepGradient、BitmapShader、ComposeShader。Shader は setColor で設定された色を置き換え、描画されるすべての要素に適用されます。
LinearGradient は直線に沿って2つ以上の色の間で滑らかな遷移を作成します。コンストラクタは始点と終点、色の配列、その位置 (tile mode) を受け取ります。tile mode はグラデーションの外側の挙動を決定します: CLAMP (最後の色の繰り返し)、MIRROR (反転)、REPEAT (繰り返し)。LinearGradient は背景の塗りつぶしやプログレスバーに広く使われます。
RadialGradient は中心から端へ円形のグラデーションを作成します。中心は座標で定義され、半径が色の遷移領域を決定します。放射状グラデーションの外観は点光源からの照明に似ています — ボタンの輝きやアクティブ要素のハイライトをシミュレートするのに使われることが多いです。
BlurMaskFilter は描画された要素の周囲にぼかし効果を追加します。コンストラクタはぼかし半径とスタイルを受け取ります: NORMAL (全方向のぼかし)、INNER (図形の内側のみ)、OUTER (外側のみ)、SOLID (図形 + 外側のぼかし)。BlurMaskFilter はあらゆる種類の Paint で機能し、影や発光効果の作成によく使われます。
val paint = Paint().apply {
setShader(LinearGradient(
0f, 0f, width, height,
intArrayOf(Color.RED, Color.BLUE),
null,
Shader.TileMode.CLAMP
))
setMaskFilter(BlurMaskFilter(20f, BlurMaskFilter.Blur.NORMAL))
}
グラデーション塗りつぶしとテキストラベル付きの円を描画するカスタム View の完全な例を見てみましょう。Paint と Canvas の組み合わせで、最小限のコードで複雑なグラフィックを作成できます。すべての設定はパフォーマンスのために初期化時にまとめられています。
class GradientCircleView@JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null
) : View(context, attrs) {
private val fillPaint = Paint().apply {
setShader(RadialGradient(
0f, 0f, 200f,
intArrayOf(Color.CYAN, Color.DKGRAY),
null, Shader.TileMode.CLAMP
))
}
private val textPaint = Paint().apply {
setColor(Color.WHITE)
setTextSize(TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 24f, resources.displayMetrics
))
setTextAlign(Paint.Align.CENTER)
setMaskFilter(BlurMaskFilter(5f, BlurMaskFilter.Blur.NORMAL))
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
canvas.drawCircle(200f, 200f, 150f, fillPaint)
canvas.drawText("Gradient", 200f, 210f, textPaint)
}
}
コードでは2つの別々の Paint オブジェクトが使われています: 1つは放射状グラデーションで円を塗りつぶす用、もう1つは BlurMaskFilter による影付きテキスト用です。この分割により、パラメータを独立して設定でき、異なる種類の要素の描画間で Paint の状態をリセットすることを避けられます。パフォーマンスを高めるため、両方の Paint は onDraw ではなくコンストラクタで作成されます。
異なるピクセル密度のデバイスでスケーリングする場合、サイズ値は TypedValue.applyDimension で再計算する必要があります。これがないと、テキストとグラデーションは mdpi と xxxhdpi の画面で異なって見えます。例ではテキストサイズが sp で設定されており、ユーザーのシステムのフォントサイズ設定に自動的に適応します。
よくある質問
Canvas は描画操作 (drawCircle、drawLine) を実行し、Paint はスタイル — 色、太さ、フォントを定義します。Canvas にはスタイル設定が含まれないため、Paint なしではどの描画操作にも視覚効果がありません。
はい、1つのPaint オブジェクトを複数の図形で再利用できます。異なる種類の要素 (背景、テキスト、輪郭) ごとに別々の Paint を作成することをお勧めしますが、図形ごとには作成しないでください — ガベージコレクタの負荷が減ります。
reset メソッドは Paint を新しいインスタンスと同等の状態に戻します。代わりにフラグ付きの set を使うこともできますが、コードの可読性には reset が推奨されます。リセット後、すべてのスタイルパラメータはデフォルト値になります。
onDraw 内で Paint を作成すると毎フレーム割り当てが発生し、GC フリーズを引き起こします。すべての Paint オブジェクトは View のコンストラクタで作成する必要があります。onDraw でセッターによるパラメータ変更は安全で、新しいオブジェクトを作成しません。
Android ではテキストは常に透明な背景で描画されます。drawText メソッドは背景矩形なしでグリフだけを出力します。テキストの下に背景が必要な場合は、まず別の Paint で drawRoundRect により矩形を描き、その後にテキストを描きます。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。