Paint στο Android: τι είναι, μέθοδοι διαμόρφωσης και πώς λειτουργεί

Συγγραφέας: IT Sectr Δημοσιεύτηκε: 2026-07-21 Χρόνος ανάγνωσης: 9 λεπ

Paint — η κύρια κλάση για τη στυλισμένη γραφικών στο Android Canvas. Καθορίζει το χρώμα, το πάχος γραμμής, το στυλ γεμίσματος, τα εφέ θολώματος και τις γραμματοσειρές για όλες τις λειτουργίες σχεδίασης στο περιβάλλον χρήστη. Χωρίς το Paint, το Canvas δεν μπορεί να εφαρμόσει οπτικά χαρακτηριστικά στα εμφανιζόμενα στοιχεία. Σύμφωνα με το Google Developers, 2026, το Paint υποστηρίζει έως 42 παραμέτρους στυλ, συμπεριλαμβανομένων των gradient και υφών.

Κύρια σημεία

  • Paint — αντικείμενο στυλισμένη για το Canvas, που περιέχει όλες τις οπτικές ρυθμίσεις σχεδίασης.
  • setColor και setAlpha ελέγχουν το χρώμα και τη διαφάνεια των γραμμών και γεμισμάτων.
  • Style καθορίζει αν σχεδιάζεται το περίγραμμα, το γέμισμα ή και οι δύο παραλλαγές ταυτόχρονα.
  • Shader επιτρέπει την εφαρμογή gradient, bitmap υφών και σύνθετων.
  • Typeface ορίζει τη γραμματοσειρά για κείμενο με υποστήριξη όλων των συστημικών γραμματοσειρών Android.

Τι είναι το Paint στο Android;

Paint — μια κλάση από το πακέτο android.graphics που αποθηκεύει όλες τις ρυθμίσεις στυλ για λειτουργίες σχεδίασης στο Canvas. Δεν περιέχει τα ίδια τα pixel, αλλά καθορίζει πώς θα εμφανίζονται οι γραμμές, τα σχήματα και το κείμενο. Κάθε κλήση μεθόδου Canvas — drawCircle, drawLine, drawText — χρησιμοποιεί το Paint για την ερμηνεία της οπτικής αναπαράστασης.

Το Paint λειτουργεί με βάση την αρχή ενός αντικειμένου διαμόρφωσης. Δημιουργείτε ένα instance, ορίζετε τις παραμέτρους μία φορά και το επαναχρησιμοποιείτε για πολλές λειτουργίες. Αυτό ελαχιστοποιεί τον αριθμό των δεσμεύσεων στον βρόχο σχεδίασης και αυξάνει την απόδοση έως και 30% σε σύγκριση με τη δημιουργία νέου αντικειμένου κάθε καρέ. Σύμφωνα με το Google I/O 2024, η βελτιστοποίηση του Paint είναι μία από τις βασικές πρακτικές για την επίτευξη 60 FPS σε προσαρμοσμένα γραφικά.

Όλες οι ρυθμίσεις του Paint χωρίζονται σε διάφορες κατηγορίες: χρώμα και διαφάνεια, στυλ περιγράμματος και γεμίσματος, εργασία με κείμενο και γραμματοσειρές, εφέ θολώματος και μάσκας. Κάθε κατηγορία διαχειρίζεται από ξεχωριστές μεθόδους setter που μπορούν να συνδυαστούν σε οποιονδήποτε συνδυασμό. Αυτό κάνει το Paint API ευέλικτο, αλλά απαιτεί κατανόηση της αλληλεπίδρασης των παραμέτρων — για παράδειγμα, το Style επηρεάζει αν το Shader εφαρμόζεται στο περίγραμμα ή στο γέμισμα.

Χρώμα και διαφάνεια στο Paint

setColor — η κύρια μέθοδος για τον ορισμό χρώματος για όλες τις επόμενες λειτουργίες σχεδίασης. Το χρώμα μεταδίδεται σε μορφή ARGB (32-bit ακέραιος αριθμός), όπου τα ανώτερα 8 bit είναι το κανάλι άλφα και τα υπόλοιπα είναι τα κανάλια κόκκινου, πράσινου και μπλε. Η τιμή 0xFF0000FF ορίζει αδιαφανές μπλε χρώμα.

Διαχείριση καναλιού άλφα

Η μέθοδος setAlpha επιτρέπει την ανεξάρτητη ρύθμιση της διαφάνειας σε εύρος από 0 (εντελώς διαφανές) έως 255 (εντελώς αδιαφανές). Σε αντίθεση με τον καθορισμό άλφα στο setColor, αυτή η μέθοδος δεν επηρεάζει την ήδη ορισμένη απόχρωση χρώματος — απλώς διαμορφώνει τη συνολική διαφάνεια. Αυτό είναι βολικό για κινούμενα σχέδια εμφάνισης και εξαφάνισης στοιχείων χωρίς αλλαγή χρώματος.

ColorFilter για διόρθωση χρώματος

ColorFilter — μηχανισμός μετασχηματισμού χρώματος κάθε pixel πριν από τη σχεδίαση. Υποστηρίζονται τρεις λειτουργίες: LightingColorFilter για πολλαπλασιασμό και πρόσθεση καναλιών, PorterDuffColorFilter για επικάλυψη με χρήση λειτουργιών ανάμειξης και ColorMatrixColorFilter για πλήρη μετασχηματισμό μήτρας. Το ColorFilter εφαρμόζεται μετά το Shader, αλλά πριν από την έξοδο στο Canvas.

Για τις περισσότερες εργασίες, αρκούν τα τυπικά setColor ή setAlpha. Το ColorFilter χρησιμοποιείται κυρίως για εφέ αποχρωματισμού, sepia ή αντιστροφής. Η χρήση του ColorFilter αυξάνει το φορτίο GPU, γι αυτό η Google συνιστά την ελαχιστοποίηση της χρήσης του σε κυκλικές κλήσεις onDraw.

ΜέθοδοςΠεριγραφήΑπόδοση
setColorΟρίζει χρώμα σε ARGBO(1) — χωρίς επιβάρυνση
setAlphaΡυθμίζει διαφάνεια (0-255)O(1) — ελαφριά λειτουργία
setColorFilterΕφαρμόζει διόρθωση χρώματοςO(n) — επηρεάζει FPS σε συχνές κλήσεις

Στυλ και πάχος γραμμής

Η μέθοδος setStyle δέχεται μία από τις τρεις τιμές Paint.Style: FILL (γέμισμα), STROKE (περίγραμμα) ή FILL_AND_STROKE (ταυτόχρονα). Από την επιλογή στυλ εξαρτάται αν το σχήμα θα εμφανίζεται ως σιλουέτα, ως σκελετός ή ως περίγραμμα με εσωτερικό γέμισμα. Από προεπιλογή, το Paint δημιουργείται με στυλ FILL.

Πάχος γραμμής και συνδέσεις

setStrokeWidth ορίζει το πάχος γραμμής σε pixel για τη λειτουργία STROKE. Για στρογγυλεμένα σχήματα και στρογγυλεμένες γωνίες χρησιμοποιούνται setStrokeCap (Cap.ROUND, BUTT, SQUARE) και setStrokeJoin (Join.MITER, ROUND, BEVEL). Αυτές οι παράμετροι επηρεάζουν κρίσιμα την εμφάνιση γραφημάτων, διαδρομών και πλαισίων σε προσαρμοσμένα View.

Σε πάχος μικρότερο από 1 pixel, η γραμμή σχεδιάζεται με υποπίξελ ακρίβεια, αλλά μπορεί να φαίνεται θολή σε οθόνες χαμηλής πυκνότητας. Για οθόνες Retina Android χρησιμοποιήστε TypedValue.applyDimension για μετατροπή dp σε pixel. Το πάχος 2 dp εξασφαλίζει καθαρή ορατότητα στις περισσότερες συσκευές.

Μοτίβα διαγράμμισης (DashPathEffect)

DashPathEffect δημιουργεί διακεκομμένες και γραμμοσκιασμένες γραμμές. Ο κατασκευαστής δέχεται έναν πίνακα μηκών εναλλασσόμενων παύλων και κενών και μια αρχική μετατόπιση φάσης. Για παράδειγμα, ο πίνακας [10, 5, 3, 5] δημιουργεί μια γραμμή με μεγάλη παύλα, σύντομο κενό, σύντομη παύλα και κενό. Αυτό το εφέ χρησιμοποιείται ενεργά σε επεξεργαστές γραφικών και εργαλεία σχολιασμού.

Ο συνδυασμός στυλ πραγματοποιείται μέσω setPathEffect. Συνδυάζοντας CornerPathEffect, DashPathEffect και DiscretePathEffect, μπορούν να δημιουργηθούν σύνθετες οπτικές γραμμές για διαγράμματα, λεζάντες και διακοσμητικά στοιχεία. Κάθε PathEffect υπολογίζεται στην CPU, επομένως σε κινούμενα σχέδια με πολλές γραμμές συνιστάται η εκ των προτέρων ψηφιοποίηση του εφέ σε 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))
}

Γραμματοσειρές και απόδοση κειμένου

Typeface — αντικείμενο που καθορίζει την οικογένεια γραμματοσειράς για όλες τις λειτουργίες κειμένου του Paint. Το Android υποστηρίζει συστημικές γραμματοσειρές (Roboto, Noto Sans), προσαρμοσμένες γραμματοσειρές από πόρους assets και γραμματοσειρές που φορτώνονται μέσω Downloadable Fonts API. Η ρύθμιση Typeface γίνεται μέσω setTypeface στο instance του Paint.

Μέγεθος κειμένου και διάστιχο

Η μέθοδος setTextSize ορίζει το μέγεθος γραμματοσειράς σε pixel. Για σωστή εμφάνιση σε διαφορετικές οθόνες, συνιστάται να ορίζετε το μέγεθος σε sp χρησιμοποιώντας TypedValue.applyDimension. Το διάστιχο ρυθμίζεται μέσω setTextScaleX για οριζόντια επέκταση και περιλαμβάνεται στην ενσωματωμένη υποστήριξη κειμένου MultiLine μέσω Canvas.drawText.

Για στοίχιση κειμένου χρησιμοποιείται setTextAlign με τιμές LEFT, CENTER και RIGHT. Στο CENTER, η συντεταγμένη x που μεταδίδεται στο drawText γίνεται το κεντρικό σημείο του κειμένου — αυτό είναι ιδιαίτερα βολικό για λεζάντες κάτω από εικονίδια και τίτλους εντός σχημάτων. Για ακριβή τοποθέτηση χρησιμοποιούνται οι μέθοδοι measureText και getTextBounds, που επιστρέφουν το πλάτος και το ορθογώνιο ορίων του κειμένου.

Υπογράμμιση και διαγραφή

Οι setUnderlineText και setStrikeThruText ενεργοποιούν την υπογράμμιση και τη διαγραφή αντίστοιχα. Αυτές οι παράμετροι λειτουργούν σε επίπεδο γραμματοσειράς και εφαρμόζονται σε όλο το κείμενο που σχεδιάζεται από το συγκεκριμένο Paint. Για ευέλικτη μορφοποίηση διαφορετικών τμημάτων της ίδιας γραμμής, χρησιμοποιήστε ξεχωριστά αντικείμενα Paint με διαφορετικές ρυθμίσεις ή εναλλάξτε τις παραμέτρους μεταξύ κλήσεων drawText.

ΜέθοδοςΣκοπόςΜονάδα μέτρησης
setTextSizeΜέγεθος γραμματοσειράςpx (pixel)
setTextAlignΟριζόντια στοίχισηLEFT, CENTER, RIGHT
setTypefaceΓραμματοσειράTypeface object
setUnderlineTextΥπογράμμισηBoolean

Gradient και προηγμένα εφέ

Shader — βασική κλάση για γέμισμα σχημάτων με gradient, bitmap υφές και σύνθετα. Μέσω της μεθόδου setShader μπορεί να οριστεί οποιαδήποτε από τις υποκλάσεις: LinearGradient, RadialGradient, SweepGradient, BitmapShader ή ComposeShader. Το Shader αντικαθιστά το χρώμα που ορίστηκε από το setColor και εφαρμόζεται σε όλα τα σχεδιασμένα στοιχεία.

Γραμμικά και ακτινικά gradient

LinearGradient δημιουργεί ομαλή μετάβαση μεταξύ δύο ή περισσότερων χρωμάτων κατά μήκος μιας ευθείας γραμμής. Ο κατασκευαστής δέχεται σημεία έναρξης και λήξης, έναν πίνακα χρωμάτων και τις θέσεις τους (λειτουργία πλακιδίου). Η λειτουργία πλακιδίου καθορίζει τη συμπεριφορά εκτός gradient: CLAMP (επανάληψη του τελευταίου χρώματος), MIRROR (κατοπτρισμός) ή REPEAT (επανάληψη). Το LinearGradient χρησιμοποιείται ενεργά για γεμίσματα φόντου και γραμμές προόδου.

RadialGradient δημιουργεί κυκλικό gradient από το κέντρο προς τις άκρες. Το κέντρο καθορίζεται από συντεταγμένες, η ακτίνα ορίζει τη ζώνη μετάβασης χρωμάτων. Η εμφάνιση του ακτινικού gradient θυμίζει φωτισμό από σημειακή πηγή — αυτό χρησιμοποιείται συχνά για προσομοίωση λάμψης κουμπιών και φωτισμού ενεργών στοιχείων.

Θόλωμα και σκιές (BlurMaskFilter)

BlurMaskFilter προσθέτει εφέ θολώματος γύρω από σχεδιασμένα στοιχεία. Ο κατασκευαστής δέχεται την ακτίνα θολώματος και το στυλ: NORMAL (θόλωμα προς όλες τις κατευθύνσεις), INNER (μόνο εντός του σχήματος), OUTER (μόνο εξωτερικά) και SOLID (σχήμα + εξωτερικό θόλωμα). Το BlurMaskFilter λειτουργεί με οποιονδήποτε τύπο Paint και χρησιμοποιείται συχνά για δημιουργία σκιών και εφέ λάμψης.

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

Παράδειγμα χρήσης Paint με Canvas

Ας δούμε ένα πλήρες παράδειγμα προσαρμοσμένου View που σχεδιάζει έναν κύκλο με γέμισμα gradient και λεζάντα κειμένου. Ο συνδυασμός Paint και Canvas επιτρέπει τη δημιουργία σύνθετων γραφικών με ελάχιστο κώδικα. Όλες οι ρυθμίσεις μεταφέρονται στην αρχικοποίηση για απόδοση.

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

Στον κώδικα χρησιμοποιούνται δύο ξεχωριστά αντικείμενα Paint: ένα για το γέμισμα του κύκλου με ακτινικό gradient, το δεύτερο για κείμενο με σκιά μέσω BlurMaskFilter. Αυτός ο διαχωρισμός επιτρέπει την ανεξάρτητη διαμόρφωση των παραμέτρων και αποφεύγει την επαναφορά της κατάστασης Paint μεταξύ σχεδίασης διαφορετικών τύπων στοιχείων. Για αύξηση της απόδοσης, και τα δύο Paint δημιουργούνται στον κατασκευαστή, όχι στο onDraw.

Κατά την κλιμάκωση σε συσκευές με διαφορετική πυκνότητα pixel, οι τιμές μεγέθους πρέπει να υπολογίζονται εκ νέου μέσω TypedValue.applyDimension. Χωρίς αυτό, το κείμενο και το gradient θα εμφανίζονται διαφορετικά σε οθόνες mdpi και xxxhdpi. Στο παράδειγμα, το μέγεθος κειμένου ορίζεται σε sp, το οποίο προσαρμόζεται αυτόματα στις συστημικές ρυθμίσεις μεγέθους γραμματοσειράς του χρήστη.

Συχνές ερωτήσεις

Ποια είναι η διαφορά μεταξύ Paint και Canvas;

Canvas εκτελεί λειτουργίες σχεδίασης (drawCircle, drawLine), ενώ το Paint καθορίζει το στυλ — χρώμα, πάχος, γραμματοσειρά. Το Canvas δεν περιέχει ρυθμίσεις στυλ, επομένως χωρίς Paint καμία λειτουργία σχεδίασης δεν έχει οπτικό αποτέλεσμα.

Μπορεί να χρησιμοποιηθεί ένα Paint για διαφορετικά σχήματα;

Ναι, ένα αντικείμενο Paint μπορεί να επαναχρησιμοποιηθεί για πολλά σχήματα. Συνιστάται η δημιουργία ξεχωριστών Paint για διαφορετικούς τύπους στοιχείων (φόντο, κείμενο, περίγραμμα), αλλά όχι για κάθε σχήμα — αυτό μειώνει το φορτίο του garbage collector.

Πώς γίνεται επαναφορά του Paint στις προεπιλεγμένες ρυθμίσεις;

Η μέθοδος reset επαναφέρει το Paint σε κατάσταση ισοδύναμη με νέο instance. Εναλλακτικά, μπορεί να χρησιμοποιηθεί το set με σημαία, αλλά το reset είναι προτιμότερο για αναγνωσιμότητα κώδικα. Μετά την επαναφορά, όλες οι παράμετροι στυλ λαμβάνουν προεπιλεγμένες τιμές.

Επηρεάζει το Paint την απόδοση στο onDraw;

Η δημιουργία Paint εντός onDraw προκαλεί δέσμευση σε κάθε καρέ, οδηγώντας σε παγώματα GC. Όλα τα αντικείμενα Paint πρέπει να δημιουργούνται στον κατασκευαστή View. Η αλλαγή παραμέτρων στο onDraw μέσω setter είναι ασφαλής και δεν δημιουργεί νέα αντικείμενα.

Πώς γίνεται διάφανο φόντο κειμένου στο Paint;

Το κείμενο στο Android σχεδιάζεται πάντα με διάφανο φόντο. Η μέθοδος drawText εμφανίζει μόνο τα γλύφω, χωρίς ορθογώνιο φόντου. Αν χρειάζεται φόντο κάτω από το κείμενο, σχεδιάστε πρώτα ένα ορθογώνιο μέσω drawRoundRect με ξεχωριστό Paint και μετά το κείμενο.

Σύνοψη

  • Paint — κλάση διαμόρφωσης για στυλισμένη γραφικών στο Canvas, καθορίζει χρώμα, πάχος, γραμματοσειρά και εφέ.
  • setColor και setAlpha ελέγχουν χρώμα και διαφάνεια με ελάχιστη επιβάρυνση.
  • Style (FILL, STROKE, FILL_AND_STROKE) καθορίζει αν σχεδιάζεται περίγραμμα, γέμισμα ή και τα δύο.
  • Typeface και setTextSize είναι υπεύθυνα για γραμματοσειρές με υποστήριξη Downloadable Fonts και προσαρμογή οθόνης.
  • Shader — LinearGradient, RadialGradient, BitmapShader — προσθέτουν gradient και υφές.
  • Δημιουργήστε Paint στον κατασκευαστή View, όχι στο onDraw, για αποφυγή παγωμάτων GC.
  • Διαχωρίστε Paint ανά τύπο στοιχείου: γέμισμα, περίγραμμα, κείμενο — για ευέλικτη διαμόρφωση και αναγνωσιμότητα κώδικα.

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης