Paint — kelas utama untuk menata grafis di Android Canvas. Ini menentukan warna, ketebalan garis, gaya isian, efek keburaman dan font untuk semua operasi menggambar di antarmuka pengguna. Tanpa Paint, Canvas tidak dapat menerapkan atribut visual ke elemen yang ditampilkan. Menurut Google Developers, 2026, Paint mendukung hingga 42 parameter gaya, termasuk gradien dan tekstur.
Poin utama
Paint — kelas dari paket android.graphics yang menyimpan semua pengaturan gaya untuk operasi menggambar di Canvas. Ini tidak berisi piksel itu sendiri, tetapi menentukan bagaimana garis, bentuk dan teks akan terlihat. Setiap panggilan metode Canvas — drawCircle, drawLine, drawText — menggunakan Paint untuk interpretasi representasi visual.
Paint bekerja berdasarkan prinsip objek konfigurasi. Anda membuat instance, mengatur parameter sekali dan menggunakannya kembali untuk banyak operasi. Ini meminimalkan jumlah alokasi dalam loop menggambar dan meningkatkan kinerja hingga 30% dibandingkan dengan membuat objek baru setiap frame. Menurut Google I/O 2024, optimasi Paint adalah salah satu praktik kunci untuk mencapai 60 FPS dalam grafis kustom.
Semua pengaturan Paint dibagi menjadi beberapa kategori: warna dan transparansi, gaya goresan dan isian, bekerja dengan teks dan font, efek keburaman dan masking. Setiap kategori dikelola oleh metode setter terpisah yang dapat dikombinasikan dalam kombinasi apa pun. Ini membuat API Paint fleksibel, tetapi membutuhkan pemahaman tentang interaksi parameter — misalnya, Style mempengaruhi apakah Shader diterapkan ke kontur atau isian.
setColor — metode utama untuk mengatur warna untuk semua operasi menggambar berikutnya. Warna dikirimkan dalam format ARGB (bilangan bulat 32-bit), di mana 8 bit atas adalah saluran alfa, dan sisanya adalah saluran merah, hijau dan biru. Nilai 0xFF0000FF mengatur warna biru buram.
Metode setAlpha memungkinkan pengaturan transparansi secara independen dalam rentang 0 (sepenuhnya transparan) hingga 255 (sepenuhnya buram). Tidak seperti menentukan alfa di setColor, metode ini tidak mempengaruhi warna yang sudah diatur — hanya memodulasi transparansi keseluruhan. Ini berguna untuk animasi muncul dan menghilangnya elemen tanpa perubahan warna.
ColorFilter — mekanisme transformasi warna setiap piksel sebelum digambar. Tiga mode didukung: LightingColorFilter untuk perkalian dan penambahan saluran, PorterDuffColorFilter untuk overlay menggunakan mode campuran dan ColorMatrixColorFilter untuk transformasi matriks penuh. ColorFilter diterapkan setelah Shader, tetapi sebelum output ke Canvas.
Untuk sebagian besar tugas, setColor atau setAlpha standar sudah cukup. ColorFilter terutama digunakan untuk efek perubahan warna, sepia atau inversi. Penggunaan ColorFilter meningkatkan beban GPU, oleh karena itu Google merekomendasikan untuk meminimalkan penggunaannya dalam panggilan siklik onDraw.
| Metode | Deskripsi | Kinerja |
|---|---|---|
| setColor | Mengatur warna dalam ARGB | O(1) — tanpa overhead |
| setAlpha | Mengatur transparansi (0-255) | O(1) — operasi ringan |
| setColorFilter | Menerapkan koreksi warna | O(n) — mempengaruhi FPS saat sering dipanggil |
Metode setStyle menerima salah satu dari tiga nilai Paint.Style: FILL (isian), STROKE (kontur) atau FILL_AND_STROKE (bersamaan). Dari pilihan gaya tergantung apakah bentuk akan ditampilkan sebagai siluet, sebagai kerangka atau sebagai kontur dengan isian internal. Secara default, Paint dibuat dengan gaya FILL.
setStrokeWidth mengatur ketebalan garis dalam piksel untuk mode STROKE. Untuk bentuk bulat dan sudut membulat digunakan setStrokeCap (Cap.ROUND, BUTT, SQUARE) dan setStrokeJoin (Join.MITER, ROUND, BEVEL). Parameter ini sangat mempengaruhi tampilan grafik, jalur dan bingkai di View kustom.
Pada ketebalan kurang dari 1 piksel, garis digambar dengan presisi subpiksel, tetapi mungkin terlihat kabur pada layar dengan kerapatan rendah. Untuk layar Retina Android gunakan TypedValue.applyDimension untuk mengonversi dp ke piksel. Ketebalan 2 dp memberikan visibilitas yang jelas di sebagian besar perangkat.
DashPathEffect membuat garis putus-putus dan garis-garis. Konstruktor menerima array panjang garis dan spasi bergantian dan pergeseran fase awal. Misalnya, array [10, 5, 3, 5] membuat garis dengan garis panjang, spasi pendek, garis pendek dan spasi. Efek ini aktif digunakan di editor grafis dan alat anotasi.
Penggabungan gaya dilakukan melalui setPathEffect. Dengan menggabungkan CornerPathEffect, DashPathEffect dan DiscretePathEffect, Anda dapat membuat garis visual yang kompleks untuk diagram, keterangan dan elemen dekoratif. Setiap PathEffect dihitung di CPU, oleh karena itu dalam animasi dengan banyak garis disarankan untuk meraster efek terlebih dahulu ke 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 — objek yang menentukan jenis huruf untuk semua operasi teks Paint. Android mendukung font sistem (Roboto, Noto Sans), font kustom dari sumber daya assets dan font yang dapat diunduh melalui Downloadable Fonts API. Pengaturan Typeface dilakukan melalui setTypeface pada instance Paint.
Metode setTextSize mengatur ukuran font dalam piksel. Untuk tampilan yang benar di layar yang berbeda, disarankan untuk menentukan ukuran dalam sp menggunakan TypedValue.applyDimension. Jarak antar baris diatur melalui setTextScaleX untuk peregangan horizontal dan termasuk dalam dukungan bawaan untuk teks MultiLine melalui Canvas.drawText.
Untuk perataan teks digunakan setTextAlign dengan nilai LEFT, CENTER dan RIGHT. Pada CENTER, koordinat x yang diteruskan ke drawText menjadi titik tengah teks — ini sangat berguna untuk keterangan di bawah ikon dan judul di dalam bentuk. Untuk penentuan posisi yang tepat digunakan metode measureText dan getTextBounds, yang mengembalikan lebar dan persegi panjang batas teks.
setUnderlineText dan setStrikeThruText mengaktifkan garis bawah dan coret. Parameter ini bekerja pada tingkat jenis huruf dan diterapkan ke semua teks yang digambar oleh Paint tersebut. Untuk format fleksibel dari berbagai bagian baris yang sama, gunakan objek Paint terpisah dengan pengaturan berbeda atau alihkan parameter di antara panggilan drawText.
| Metode | Tujuan | Satuan ukuran |
|---|---|---|
| setTextSize | Ukuran font | px (piksel) |
| setTextAlign | Perataan horizontal | LEFT, CENTER, RIGHT |
| setTypeface | Jenis huruf | Typeface object |
| setUnderlineText | Garis bawah | Boolean |
Shader — kelas dasar untuk mengisi bentuk dengan gradien, tekstur bitmap dan komposit. Melalui metode setShader dapat ditetapkan salah satu dari subkelas: LinearGradient, RadialGradient, SweepGradient, BitmapShader atau ComposeShader. Shader menggantikan warna yang diatur oleh setColor dan diterapkan ke semua elemen yang digambar.
LinearGradient menciptakan transisi halus antara dua atau lebih warna sepanjang garis lurus. Konstruktor menerima titik awal dan akhir, array warna dan posisinya (mode ubin). Mode ubin menentukan perilaku di luar gradien: CLAMP (pengulangan warna terakhir), MIRROR (pencerminan) atau REPEAT (pengulangan). LinearGradient aktif digunakan untuk isian latar belakang dan bilah kemajuan.
RadialGradient menciptakan gradien melingkar dari pusat ke tepi. Pusat ditentukan oleh koordinat, radius menentukan zona transisi warna. Tampilan gradien radial menyerupai pencahayaan dari sumber titik — ini sering digunakan untuk simulasi cahaya tombol dan penerangan elemen aktif.
BlurMaskFilter menambahkan efek keburaman di sekitar elemen yang digambar. Konstruktor menerima radius keburaman dan gaya: NORMAL (keburaman ke segala arah), INNER (hanya di dalam bentuk), OUTER (hanya di luar) dan SOLID (bentuk + keburaman eksternal). BlurMaskFilter bekerja dengan semua jenis Paint dan sering digunakan untuk membuat bayangan dan efek cahaya.
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))
}
Mari kita lihat contoh lengkap View kustom yang menggambar lingkaran dengan isian gradien dan keterangan teks. Kombinasi Paint dan Canvas memungkinkan pembuatan grafis kompleks dengan kode minimal. Semua pengaturan dipindahkan ke inisialisasi untuk kinerja.
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("Gradien", 200f, 210f, textPaint)
}
}
Dalam kode digunakan dua objek Paint terpisah: satu untuk mengisi lingkaran dengan gradien radial, yang kedua untuk teks dengan bayangan melalui BlurMaskFilter. Pemisahan seperti ini memungkinkan konfigurasi parameter secara independen dan menghindari pengaturan ulang status Paint antara menggambar berbagai jenis elemen. Untuk meningkatkan kinerja, kedua Paint dibuat di konstruktor, bukan di onDraw.
Saat penskalaan pada perangkat dengan kerapatan piksel berbeda, nilai ukuran harus dihitung ulang melalui TypedValue.applyDimension. Tanpa ini, teks dan gradien akan terlihat berbeda pada layar mdpi dan xxxhdpi. Dalam contoh, ukuran teks diatur dalam sp, yang secara otomatis menyesuaikan dengan pengaturan ukuran font sistem pengguna.
Pertanyaan yang sering diajukan
Canvas melakukan operasi menggambar (drawCircle, drawLine), sedangkan Paint menentukan gaya — warna, ketebalan, font. Canvas tidak berisi pengaturan gaya, oleh karena itu tanpa Paint tidak ada operasi menggambar yang memiliki efek visual.
Ya, satu objek Paint dapat digunakan kembali untuk banyak bentuk. Disarankan untuk membuat Paint terpisah untuk berbagai jenis elemen (latar belakang, teks, kontur), tetapi tidak untuk setiap bentuk — ini mengurangi beban pada garbage collector.
Metode reset mengembalikan Paint ke status yang setara dengan instance baru. Alternatifnya, set dengan flag dapat digunakan, tetapi reset lebih disukai untuk keterbacaan kode. Setelah reset, semua parameter gaya mengambil nilai default.
Pembuatan Paint di dalam onDraw menyebabkan alokasi di setiap frame, yang mengakibatkan pembekuan GC. Semua objek Paint harus dibuat di konstruktor View. Mengubah parameter di onDraw melalui setter aman dan tidak membuat objek baru.
Teks di Android selalu digambar dengan latar belakang transparan. Metode drawText hanya menampilkan glyphs, tanpa persegi panjang latar belakang. Jika diperlukan latar belakang di bawah teks, gambar dulu persegi panjang melalui drawRoundRect dengan Paint terpisah, lalu teks.
Kesimpulan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga