Paint در Android: چیست، روش‌های تنظیم و چگونه کار می‌کند

نویسنده: IT Sectr منتشر شده: 2026-07-21 زمان مطالعه: 9 دقیقه

Paint — کلاس اصلی برای استایل‌دهی گرافیک در Android Canvas است. این کلاس رنگ، ضخامت خط، استایل پر کردن، افکت‌های محو و فونت‌ها را برای تمام عملیات نقاشی در رابط کاربری تعیین می‌کند. بدون Paint، Canvas نمی‌تواند ویژگی‌های بصری را به عناصر نمایش داده شده اعمال کند. به گفته Google Developers، 2026، Paint تا 42 پارامتر استایل از جمله گرادینت‌ها و بافت‌ها را پشتیبانی می‌کند.

نکات اصلی

  • Paint — شی استایل‌دهی برای Canvas، شامل تمام تنظیمات بصری نقاشی.
  • setColor و setAlpha رنگ و شفافیت خطوط و پرکننده‌ها را کنترل می‌کنند.
  • Style تعیین می‌کند که آیا خط دور، پر کردن یا هر دو همزمان رسم شوند.
  • Shader امکان اعمال گرادینت‌ها، بافت‌های بیت‌مپ و ترکیب‌ها را فراهم می‌کند.
  • Typeface فونت متن را با پشتیبانی از تمام فونت‌های سیستمی Android تنظیم می‌کند.

Paint در Android چیست؟

Paint — کلاسی از بسته android.graphics است که تمام تنظیمات استایل را برای عملیات نقاشی روی Canvas ذخیره می‌کند. این کلاس خود پیکسل‌ها را شامل نمی‌شود، بلکه تعیین می‌کند خطوط، اشکال و متن چگونه به نظر برسند. هر فراخوانی متد Canvas — drawCircle، drawLine، drawText — از Paint برای تفسیر نمایش بصری استفاده می‌کند.

Paint بر اساس اصل شی پیکربندی کار می‌کند. شما یک نمونه ایجاد می‌کنید، پارامترها را یک بار تنظیم می‌کنید و آن را برای عملیات متعدد استفاده مجدد می‌کنید. این کار تعداد تخصیص‌ها در حلقه رسم را به حداقل می‌رساند و عملکرد را تا 30٪ در مقایسه با ایجاد یک شی جدید در هر فریم افزایش می‌دهد. به گفته Google I/O 2024، بهینه‌سازی Paint یکی از روش‌های کلیدی برای دستیابی به 60 FPS در گرافیک سفارشی است.

تمام تنظیمات Paint به چند دسته تقسیم می‌شوند: رنگ و شفافیت، استایل خط و پر کردن، کار با متن و فونت‌ها، افکت‌های محو و ماسک‌گذاری. هر دسته توسط متدهای setter جداگانه‌ای مدیریت می‌شود که می‌توان آنها را در هر ترکیبی با هم به کار برد. این باعث می‌شود API Paint انعطاف‌پذیر باشد، اما نیاز به درک تعامل پارامترها دارد — برای مثال، Style تأثیر می‌گذارد که Shader روی خط دور یا پر کردن اعمال شود.

رنگ و شفافیت در Paint

setColor — روش اصلی تنظیم رنگ برای تمام عملیات نقاشی بعدی است. رنگ در قالب ARGB (عدد صحیح 32 بیتی) منتقل می‌شود، که در آن 8 بیت بالایی کانال آلفا و بقیه کانال‌های قرمز، سبز و آبی هستند. مقدار 0xFF0000FF یک رنگ آبی غیرشفاف تنظیم می‌کند.

مدیریت کانال آلفا

متد setAlpha امکان تنظیم مستقل شفافیت را در محدوده 0 (کاملاً شفاف) تا 255 (کاملاً غیرشفاف) فراهم می‌کند. برخلاف مشخص کردن آلفا در setColor، این متد بر روی رنگ قبلاً تنظیم شده تأثیر نمی‌گذارد — فقط شفافیت کلی را تعدیل می‌کند. این برای انیمیشن‌های ظاهر و ناپدید شدن عناصر بدون تغییر رنگ مفید است.

ColorFilter برای تصحیح رنگ

ColorFilter — مکانیزم تبدیل رنگ هر پیکسل قبل از رسم است. سه حالت پشتیبانی می‌شود: LightingColorFilter برای ضرب و جمع کانال‌ها، PorterDuffColorFilter برای روی هم‌گذاری با استفاده از حالت‌های ترکیب و ColorMatrixColorFilter برای تبدیل ماتریسی کامل. ColorFilter بعد از Shader اما قبل از خروجی به Canvas اعمال می‌شود.

برای بیشتر کارها، setColor یا setAlpha استاندارد کافی است. ColorFilter عمدتاً برای افکت‌های بی‌رنگ کردن، سپیا یا معکوس کردن استفاده می‌شود. استفاده از 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 ضخامت خط را بر حسب پیکسل برای حالت STROKE تنظیم می‌کند. برای اشکال گرد و گوشه‌های گرد از setStrokeCap (Cap.ROUND، BUTT، SQUARE) و setStrokeJoin (Join.MITER، ROUND، BEVEL) استفاده می‌شود. این پارامترها تأثیر مهمی بر ظاهر نمودارها، مسیرها و قاب‌ها در Viewهای سفارشی دارند.

در ضخامت کمتر از 1 پیکسل، خط با دقت زیرپیکسلی رسم می‌شود، اما ممکن است در صفحه‌های با تراکم پایین تار به نظر برسد. برای نمایشگرهای Retina Android از TypedValue.applyDimension برای تبدیل dp به پیکسل استفاده کنید. ضخامت 2 dp دید واضحی را در بیشتر دستگاه‌ها فراهم می‌کند.

الگوهای خط‌چین (DashPathEffect)

DashPathEffect خطوط نقطه‌چین و خط‌چین ایجاد می‌کند. سازنده آرایه‌ای از طول‌های خط‌چین‌ها و فاصله‌های متناوب و شیفت فاز اولیه را می‌پذیرد. به عنوان مثال، آرایه [10, 5, 3, 5] یک خط با خط‌چین بلند، فاصله کوتاه، خط‌چین کوتاه و فاصله ایجاد می‌کند. این افکت در ویرایشگرهای گرافیکی و ابزارهای حاشیه‌نویسی استفاده می‌شود.

ترکیب استایل‌ها از طریق setPathEffect انجام می‌شود. با ترکیب CornerPathEffect، DashPathEffect و DiscretePathEffect می‌توان خطوط بصری پیچیده‌ای برای نمودارها، زیرنویس‌ها و عناصر تزئینی ایجاد کرد. هر PathEffect روی CPU محاسبه می‌شود، بنابراین در انیمیشن‌های با تعداد زیادی خط توصیه می‌شود افکت را از قبل در Bitmap rasterize کنید.

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 روی نمونه Paint انجام می‌شود.

اندازه متن و فاصله بین خطوط

متد setTextSize اندازه قلم را بر حسب پیکسل تنظیم می‌کند. برای نمایش صحیح در صفحه‌های مختلف توصیه می‌شود اندازه را با استفاده از TypedValue.applyDimension بر حسب sp مشخص کنید. فاصله بین خطوط با setTextScaleX برای کشش افقی تنظیم می‌شود و در پشتیبانی داخلی متن MultiLine از طریق Canvas.drawText گنجانده شده است.

برای تراز کردن متن از setTextAlign با مقادیر LEFT، CENTER و RIGHT استفاده می‌شود. در CENTER، مختصات x ارسال شده به drawText به نقطه مرکزی متن تبدیل می‌شود — این به ویژه برای زیرنویس‌های زیر آیکون‌ها و عنوان‌های داخل اشکال مفید است. برای موقعیت‌یابی دقیق از متدهای measureText و getTextBounds استفاده می‌شود که عرض و مستطیل مرزهای متن را برمی‌گردانند.

زیرخط و خط خورده

setUnderlineText و setStrikeThruText به ترتیب زیرخط و خط خورده را فعال می‌کنند. این پارامترها در سطح قلم کار می‌کنند و به کل متنی که توسط Paint رسم می‌شود اعمال می‌گردند. برای قالب‌بندی منعطف بخش‌های مختلف یک خط، از اشیاء Paint جداگانه با تنظیمات مختلف استفاده کنید یا پارامترها را بین فراخوانی‌های drawText تغییر دهید.

متدهدفواحد اندازه‌گیری
setTextSizeاندازه قلمpx (پیکسل)
setTextAlignتراز افقیLEFT, CENTER, RIGHT
setTypefaceقلمTypeface object
setUnderlineTextزیرخطBoolean

گرادینت‌ها و افکت‌های پیشرفته

Shader — کلاس پایه برای پر کردن اشکال با گرادینت‌ها، بافت‌های بیت‌مپ و ترکیب‌ها. از طریق متد setShader می‌توان هر یک از زیرکلاس‌ها را تعیین کرد: LinearGradient، RadialGradient، SweepGradient، BitmapShader یا ComposeShader. Shader جایگزین رنگ تعیین شده توسط setColor می‌شود و به تمام عناصر رسم شده اعمال می‌گردد.

گرادینت‌های خطی و شعاعی

LinearGradient یک انتقال صاف بین دو یا چند رنگ در امتداد یک خط مستقیم ایجاد می‌کند. سازنده نقاط شروع و پایان، آرایه رنگ‌ها و موقعیت‌های آنها (حالت کاشی) را می‌پذیرد. حالت کاشی رفتار خارج از گرادینت را تعیین می‌کند: CLAMP (تکرار آخرین رنگ)، MIRROR (بازتاب) یا REPEAT (تکرار). LinearGradient برای پرکننده‌های پس‌زمینه و نوارهای پیشرفت استفاده می‌شود.

RadialGradient یک گرادینت دایره‌ای از مرکز به لبه‌ها ایجاد می‌کند. مرکز با مختصات تعیین می‌شود، شعاع ناحیه انتقال رنگ را مشخص می‌کند. ظاهر گرادینت شعاعی شبیه نورپردازی از یک منبع نوری نقطه‌ای است — این اغلب برای شبیه‌سازی درخشش دکمه‌ها و نور پس‌زمینه عناصر فعال استفاده می‌شود.

محو و سایه (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 سفارشی را بررسی کنیم که یک دایره با پرکننده گرادینت و زیرنویس متنی رسم می‌کند. ترکیب Paint و Canvas امکان ایجاد گرافیک پیچیده با حداقل کد را فراهم می‌کند. تمام تنظیمات برای عملکرد به initialization منتقل شده‌اند.

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("گرادینت", 200f, 210f, textPaint)
    }
}

در کد از دو شی Paint جداگانه استفاده شده است: یکی برای پر کردن دایره با گرادینت شعاعی، دومی برای متن با سایه از طریق BlurMaskFilter. این جداسازی امکان پیکربندی مستقل پارامترها و جلوگیری از بازنشانی وضعیت Paint بین رسم انواع مختلف عناصر را فراهم می‌کند. برای افزایش عملکرد، هر دو Paint در سازنده ایجاد می‌شوند، نه در onDraw.

در مقیاس‌بندی روی دستگاه‌هایی با تراکم پیکسل متفاوت، مقادیر اندازه باید از طریق TypedValue.applyDimension دوباره محاسبه شوند. بدون این، متن و گرادینت در صفحه‌های mdpi و xxxhdpi متفاوت به نظر می‌رسند. در مثال، اندازه متن بر حسب sp تنظیم شده است که به طور خودکار با تنظیمات اندازه قلم سیستم کاربر تطبیق می‌یابد.

سوالات متداول

تفاوت Paint با Canvas چیست؟

Canvas عملیات نقاشی (drawCircle، drawLine) را انجام می‌دهد و Paint استایل — رنگ، ضخامت، فونت را تعیین می‌کند. Canvas شامل تنظیمات استایل نیست، بنابراین بدون Paint هیچ عملیات نقاشی تأثیر بصری ندارد.

آیا می‌توان از یک Paint برای اشکال مختلف استفاده کرد؟

بله، یک شی Paint را می‌توان برای چندین شکل استفاده مجدد کرد. توصیه می‌شود Paintهای جداگانه برای انواع مختلف عناصر (پس‌زمینه، متن، خط دور) ایجاد کنید، اما نه برای هر شکل — این کار بار روی garbage collector را کاهش می‌دهد.

چگونه Paint را به تنظیمات پیش‌فرض بازنشانی کنیم؟

متد reset Paint را به حالتی معادل یک نمونه جدید بازمی‌گرداند. به طور جایگزین می‌توان از set با flag استفاده کرد، اما reset برای خوانایی کód ترجیح داده می‌شود. پس از بازنشانی، تمام پارامترهای استایل مقادیر پیش‌فرض می‌گیرند.

آیا 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 — گرادینت‌ها و بافت‌ها را اضافه می‌کنند.
  • Paint را در سازنده View ایجاد کنید، نه در onDraw، برای جلوگیری از توقف GC.
  • Paint را بر اساس نوع عناصر تقسیم کنید: پر کردن، خط دور، متن — برای پیکربندی منعطف و خوانایی کد.

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید