Paint trong Android: nó là gì, phương pháp cấu hình và cách hoạt động

Tác giả: IT Sectr Đã đăng: 2026-07-21 Thời gian đọc: 9 phút

Paint là lớp chính để tạo kiểu đồ họa trong Android Canvas. Nó xác định màu sắc, độ dày đường kẻ, kiểu tô màu, hiệu ứng làm mờ và phông chữ cho tất cả các thao tác vẽ trong giao diện người dùng. Nếu không có Paint, Canvas không thể áp dụng các thuộc tính trực quan cho các phần tử được hiển thị. Theo Google Developers, 2026, Paint hỗ trợ tới 42 tham số kiểu, bao gồm gradient và họa tiết.

Điểm chính

  • Paint là một đối tượng tạo kiểu cho Canvas, chứa tất cả cài đặt vẽ trực quan.
  • setColorsetAlpha kiểm soát màu sắc và độ trong suốt của đường kẻ và phần tô.
  • Style xác định xem đường viền, tô màu hay cả hai được vẽ cùng lúc.
  • Shader cho phép áp dụng gradient, họa tiết bitmap và tổng hợp.
  • Typeface đặt phông chữ cho văn bản với hỗ trợ tất cả các phông chữ hệ thống Android.

Paint trong Android là gì?

Paint là một lớp từ gói android.graphics lưu trữ tất cả cài đặt kiểu cho các thao tác vẽ trên Canvas. Nó không chứa pixel mà xác định cách các đường kẻ, hình dạng và văn bản sẽ trông như thế nào. Mỗi lần gọi phương thức Canvas — drawCircle, drawLine, drawText — sử dụng Paint để diễn giải biểu diễn trực quan.

Paint hoạt động theo nguyên tắc đối tượng cấu hình. Bạn tạo một thể hiện, đặt tham số một lần và sử dụng lại cho nhiều thao tác. Điều này giảm thiểu cấp phát trong vòng lặp vẽ và cải thiện hiệu suất lên tới 30% so với việc tạo đối tượng mới mỗi khung hình. Theo Google I/O 2024, tối ưu hóa Paint là một trong những thực hành chính để đạt 60 FPS trong đồ họa tùy chỉnh.

Tất cả cài đặt Paint được chia thành nhiều danh mục: màu sắc và độ trong suốt, kiểu nét vẽ và tô màu, xử lý văn bản và phông chữ, hiệu ứng làm mờ và mặt nạ. Mỗi danh mục được điều khiển bởi các phương thức setter độc lập có thể kết hợp theo bất kỳ sự kết hợp nào. Điều này làm cho API Paint trở nên linh hoạt, nhưng đòi hỏi phải hiểu sự tương tác của các tham số — ví dụ, Style ảnh hưởng đến việc Shader được áp dụng cho nét vẽ hay phần tô.

Màu sắc và độ trong suốt trong Paint

setColor là phương thức chính để đặt màu cho tất cả các thao tác vẽ tiếp theo. Màu sắc được truyền ở định dạng ARGB (số nguyên 32 bit), trong đó 8 bit cao là kênh alpha và phần còn lại là các kênh đỏ, xanh lục và xanh lam. Giá trị 0xFF0000FF đặt màu xanh lam đục.

Quản lý kênh alpha

Phương thức setAlpha cho phép điều chỉnh độ trong suốt một cách độc lập trong phạm vi từ 0 (hoàn toàn trong suốt) đến 255 (hoàn toàn đục). Không giống như chỉ định alpha trong setColor, phương thức này không ảnh hưởng đến tông màu đã đặt — nó chỉ điều chỉnh độ trong suốt tổng thể. Điều này thuận tiện cho việc tạo hoạt cảnh xuất hiện và biến mất của các phần tử mà không thay đổi màu sắc.

ColorFilter cho hiệu chỉnh màu

ColorFilter là một cơ chế biến đổi màu của từng pixel trước khi kết xuất. Ba chế độ được hỗ trợ: LightingColorFilter để nhân và cộng kênh, PorterDuffColorFilter để đèp chồng bằng chế độ hòa trộn và ColorMatrixColorFilter để biến đổi ma trận đầy đủ. ColorFilter được áp dụng sau Shader nhưng trước khi xuất ra Canvas.

Đối với hầu hết các tác vụ, setColor hoặc setAlpha tiêu chuẩn là đủ. ColorFilter chủ yếu được sử dụng cho các hiệu ứng giảm bão hòa, màu nâu đỏ hoặc đảo ngược. Sử dụng ColorFilter làm tăng tải GPU, vì vậy Google khuyên nên giảm thiểu việc sử dụng nó trong các lệnh gọi theo chu kỳ tới onDraw.

Phương thứcMô tảHiệu suất
setColorĐặt màu ở ARGBO(1) — không có chi phí
setAlphaĐiều chỉnh độ trong suốt (0-255)O(1) — thao tác nhẹ
setColorFilterÁp dụng hiệu chỉnh màuO(n) — ảnh hưởng FPS khi gọi thường xuyên

Kiểu và độ dày đường kẻ

Phương thức setStyle chấp nhận một trong ba giá trị Paint.Style: FILL (tô), STROKE (đường viền) hoặc FILL_AND_STROKE (cả hai). Việc chọn kiểu xác định xem một hình dạng sẽ được hiển thị dưới dạng hình bóng, khung dây hay đường viền có tô bên trong. Theo mặc định, Paint được tạo với kiểu FILL.

Độ dày đường kẻ và kết nối

setStrokeWidth đặt độ dày đường kẻ bằng pixel cho chế độ STROKE. Đối với hình tròn và góc bo tròn, sử dụng setStrokeCap (Cap.ROUND, BUTT, SQUARE) và setStrokeJoin (Join.MITER, ROUND, BEVEL). Các tham số này ảnh hưởng nghiêm trọng đến giao diện của đồ thị, đường dẫn và đường viền trong các View tùy chỉnh.

Ở độ dày dưới 1 pixel, một đường được vẽ với độ chính xác subpixel nhưng có thể trông bị mờ trên màn hình mật độ thấp. Đối với màn hình Retina Android, hãy sử dụng TypedValue.applyDimension để chuyển đổi dp thành pixel. Độ dày 2 dp đảm bảo hiển thị rõ ràng trên hầu hết các thiết bị.

Mẫu gạch ngang (DashPathEffect)

DashPathEffect tạo các đường đứt nét và gạch nối. Hàm tạo chấp nhận một mảng độ dài gạch ngang và khoảng trống xen kẽ và độ lệch pha ban đầu. Ví dụ, mảng [10, 5, 3, 5] tạo một đường có gạch dài, khoảng trống ngắn, gạch ngắn và khoảng trống. Hiệu ứng này được sử dụng tích cực trong các trình chỉnh sửa đồ họa và công cụ chú thích.

Việc kết hợp các kiểu được thực hiện thông qua setPathEffect. Bằng cách kết hợp CornerPathEffect, DashPathEffect và DiscretePathEffect, bạn có thể tạo các đường trực quan phức tạp cho biểu đồ, nhãn và các phần tử trang trí. Mỗi PathEffect được tính toán trên CPU, vì vậy trong các hoạt ảnh có nhiều đường, nên rasterize trước hiệu ứng vào Bitmap.

kotlin
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))
}

Phông chữ và kết xuất văn bản

Typeface là một đối tượng xác định kiểu chữ cho tất cả các thao tác văn bản của Paint. Android hỗ trợ phông chữ hệ thống (Roboto, Noto Sans), phông chữ tùy chỉnh từ tài nguyên assets và phông chữ có thể tải xuống qua API Downloadable Fonts. Typeface được đặt bằng cách sử dụng setTypeface trên một thể hiện Paint.

Kích thước văn bản và khoảng cách dòng

Phương thức setTextSize đặt kích thước phông chữ bằng pixel. Để hiển thị chính xác trên các màn hình khác nhau, nên chỉ định kích thước bằng sp bằng cách sử dụng TypedValue.applyDimension. Khoảng cách dòng được điều chỉnh bằng setTextScaleX để kéo dãn ngang và được hỗ trợ bởi văn bản nhiều dòng tích hợp qua Canvas.drawText.

Để căn chỉnh văn bản, setTextAlign được sử dụng với các giá trị LEFT, CENTER và RIGHT. Với CENTER, tọa độ x được truyền cho drawText trở thành điểm trung tâm của văn bản — điều này đặc biệt thuận tiện cho các nhãn dưới biểu tượng và tiêu đề bên trong hình dạng. Để định vị chính xác, các phương thức measureText và getTextBounds được sử dụng, trả về chiều rộng và hình chữ nhật bao quanh của văn bản.

Gạch chân và gạch ngang

setUnderlineTextsetStrikeThruText bật lần lượt gạch chân và gạch ngang. Các tham số này hoạt động ở cấp độ kiểu chữ và áp dụng cho tất cả văn bản được vẽ bởi Paint này. Để định dạng linh hoạt các phần khác nhau của cùng một chuỗi, hãy sử dụng các đối tượng Paint riêng biệt với các cài đặt khác nhau hoặc chuyển đổi tham số giữa các lệnh gọi drawText.

Phương thứcMục đíchĐơn vị
setTextSizeKích thước phông chữpx (pixel)
setTextAlignCăn chỉnh ngangLEFT, CENTER, RIGHT
setTypefaceKiểu chữĐối tượng Typeface
setUnderlineTextGạch chânBoolean

Gradient và hiệu ứng nâng cao

Shader là lớp cơ sở để tô các hình dạng bằng gradient, họa tiết bitmap và tổng hợp. Thông qua phương thức setShader, bạn có thể gán bất kỳ lớp con nào của nó: LinearGradient, RadialGradient, SweepGradient, BitmapShader hoặc ComposeShader. Shader thay thế màu được đặt bởi setColor và được áp dụng cho tất cả các phần tử được vẽ.

Gradient tuyến tính và xuyên tâm

LinearGradient tạo một chuyển tiếp mượt mà giữa hai hoặc nhiều màu dọc theo một đường thẳng. Hàm tạo chấp nhận điểm bắt đầu và kết thúc, một mảng màu và vị trí của chúng (chế độ tile). Chế độ tile xác định hành vi vượt ra ngoài gradient: CLAMP (lặp lại màu cuối cùng), MIRROR (phản chiếu) hoặc REPEAT (lặp lại). LinearGradient được sử dụng tích cực cho tô nền và thanh tiến trình.

RadialGradient tạo một gradient tròn từ trung tâm ra các cạnh. Trung tâm được chỉ định bằng tọa độ, bán kính xác định vùng chuyển tiếp màu. Giao diện của gradient xuyên tâm giống như ánh sáng từ một nguồn điểm — điều này thường được sử dụng để mô phỏng độ sáng của nút và làm nổi bật các phần tử hoạt động.

Làm mờ và bóng (BlurMaskFilter)

BlurMaskFilter thêm hiệu ứng làm mờ xung quanh các phần tử được vẽ. Hàm tạo chấp nhận bán kính làm mờ và một kiểu: NORMAL (làm mờ mọi hướng), INNER (chỉ bên trong hình dạng), OUTER (chỉ bên ngoài) và SOLID (hình dạng + làm mờ bên ngoài). BlurMaskFilter hoạt động với mọi loại Paint và thường được sử dụng để tạo bóng và hiệu ứng phát sáng.

kotlin
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))
}

Ví dụ sử dụng Paint với Canvas

Hãy xem xét một ví dụ hoàn chỉnh về View tùy chỉnh vẽ một hình tròn với tô gradient và nhãn văn bản. Sự kết hợp giữa Paint và Canvas cho phép tạo đồ họa phức tạp với mã tối thiểu. Tất cả cài đặt được chuyển vào khởi tạo để tăng hiệu suất.

kotlin
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)
    }
}

Mã sử dụng hai đối tượng Paint riêng biệt: một để tô hình tròn bằng gradient xuyên tâm và đối tượng thứ hai cho văn bản có bóng qua BlurMaskFilter. Sự tách biệt này cho phép cấu hình tham số một cách độc lập và tránh đặt lại trạng thái Paint giữa việc vẽ các loại phần tử khác nhau. Để cải thiện hiệu suất, cả hai đối tượng Paint được tạo trong hàm tạo, không phải trong onDraw.

Khi thay đổi tỷ lệ trên các thiết bị có mật độ pixel khác nhau, các giá trị kích thước phải được tính toán lại bằng TypedValue.applyDimension. Nếu không, văn bản và gradient sẽ trông khác nhau trên màn hình mdpi và xxxhdpi. Trong ví dụ, kích thước văn bản được chỉ định bằng sp, tự động thích ứng với cài đặt kích thước phông chữ hệ thống của người dùng.

Câu hỏi thường gặp

Paint khác Canvas như thế nào?

Canvas thực hiện các thao tác vẽ (drawCircle, drawLine), trong khi Paint xác định kiểu — màu sắc, độ dày, phông chữ. Canvas không chứa cài đặt kiểu, vì vậy nếu không có Paint, bất kỳ thao tác vẽ nào cũng không có hiệu ứng trực quan.

Có thể sử dụng một Paint cho các hình dạng khác nhau không?

Có, một đối tượng Paint duy nhất có thể được tái sử dụng cho nhiều hình dạng. Nên tạo các đối tượng Paint riêng cho các loại phần tử khác nhau (nền, văn bản, đường viền), nhưng không phải cho mỗi hình dạng — điều này giảm tải cho bộ thu gom rác.

Làm cách nào để đặt lại Paint về cài đặt mặc định?

Phương thức reset đưa Paint về trạng thái tương đương với một thể hiện mới. Thay vào đó, bạn có thể sử dụng set với cờ, nhưng reset được ưu tiên hơn cho khả năng đọc mã. Sau khi đặt lại, tất cả các tham số kiểu lấy giá trị mặc định.

Paint có ảnh hưởng đến hiệu suất trong onDraw không?

Tạo Paint bên trong onDraw gây cấp phát trong mỗi khung hình, dẫn đến đóng băng GC. Tất cả các đối tượng Paint nên được tạo trong hàm tạo View. Thay đổi tham số trong onDraw qua setter là an toàn và không tạo đối tượng mới.

Làm cách nào để tạo nền trong suốt cho văn bản trong Paint?

Văn bản trong Android luôn được vẽ với nền trong suốt. Phương thức drawText chỉ xuất ra glyph, không có hình chữ nhật nền. Nếu cần nền dưới văn bản, trước tiên hãy vẽ một hình chữ nhật bằng drawRoundRect với Paint riêng, sau đó vẽ văn bản.

Tổng kết

  • Paint là một lớp cấu hình để tạo kiểu đồ họa trên Canvas, xác định màu sắc, độ dày, phông chữ và hiệu ứng.
  • setColorsetAlpha kiểm soát màu sắc và độ trong suốt với chi phí tối thiểu.
  • Style (FILL, STROKE, FILL_AND_STROKE) xác định xem đường viền, tô màu hay cả hai được vẽ.
  • TypefacesetTextSize xử lý phông chữ với hỗ trợ Downloadable Fonts và thích ứng màn hình.
  • Shader — LinearGradient, RadialGradient, BitmapShader — thêm gradient và họa tiết.
  • Tạo Paint trong hàm tạo View, không phải trong onDraw, để ngăn đóng băng GC.
  • Phân tách Paint theo loại phần tử: tô, đường viền, văn bản — để cấu hình linh hoạt và mã dễ đọc.

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm