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 إلى عدة فئات: اللون والشفافية، نمط الحدود والتعبئة، معالجة النص والخطوط، تأثيرات التمويه والأقنعة. تتحكم في كل فئة طرق ضبط مستقلة يمكن دمجها بأي تركيبة. ما يجعل 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). تؤثر هذه المعلمات بشكل حاسم على مظهر الرسوم البيانية والمسارات والحدود في العروض المخصصة.

عند سمك أقل من 1 بكسل، يتم رسم الخط بدقة دون البكسل ولكنه قد يبدو ضبابيًا على شاشات منخفضة الكثافة. لشاشات Retina في Android، استخدم TypedValue.applyDimension لتحويل dp إلى بكسلات. يوفر سمك 2 dp رؤية واضحة على معظم الأجهزة.

أنماط الشرطات (DashPathEffect)

DashPathEffect ينشئ خطوطًا متقطعة ومنقطة. يقبل المنشئ مصفوفة من أطوال الشرطات والفجوات المتبادلة وإزاحة المرحلة الابتدائية. على سبيل المثال، تنشئ المصفوفة [10, 5, 3, 5] خطًا بشرطة طويلة، فجوة قصيرة، شرطة قصيرة وفجوة. يتم استخدام هذا التأثير بنشاط في محررات الرسوم وأدوات التعليق.

يتم الدمج بين الأنماط من خلال setPathEffect. من خلال الدمج بين CornerPathEffect، DashPathEffect و DiscretePathEffect، يمكنك إنشاء خطوط بصرية معقدة للرسوم البيانية والتسميات والعناصر الزخرفية. يتم حساب كل PathEffect على وحدة المعالجة المركزية، لذا في الرسوم المتحركة بالعديد من الخطوط، يوصى بتحويل التأثير مسبقًا إلى 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. يتم تعيين Typeface باستخدام setTypeface على مثال Paint.

حجم النص وتباعد الأسطر

تعين الطريقة setTextSize حجم الخط بالبكسل. للعرض الصحيح على شاشات مختلفة، يوصى بتحديد الحجم بوحدة sp باستخدام TypedValue.applyDimension. يتم ضبط تباعد الأسطر باستخدام setTextScaleX للتمديد الأفقي ويدعمه النص متعدد الأسطر المضمن عبر Canvas.drawText.

لمحاذاة النص، تستخدم setTextAlign مع القيم LEFT، CENTER و RIGHT. مع CENTER، تصبح الإحداثية x الممررة إلى drawText هي النقطة المركزية للنص — هذا مفيد خاصة للتسميات تحت الأيقونات والعناوين داخل الأشكال. للتوضع الدقيق، تستخدم طريقتي measureText و getTextBounds، والتان تعيدان العرض ومستطيل الحدود للنص.

التسطير والشطب

setUnderlineText و setStrikeThruText يُمكّنان التسطير والشطب على التوالي. تعمل هذه المعلمات على مستوى الخط وتنطبق على جميع النصوص التي يرسمها Paint. لتنسيق مرن لأجزاء مختلفة من نفس السلسلة، استخدم كائنات Paint منفصلة بإعدادات مختلفة أو بدّل بين المعلمات بين استدعاءات drawText.

الطريقةالغرضوحدة القياس
setTextSizeحجم الخطpx (بكسل)
setTextAlignالمحاذاة الأفقيةLEFT، CENTER، RIGHT
setTypefaceخط الطباعةكائن Typeface
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

لننظر إلى مثال كامل لعرض مخصص يرسم دائرة بتعبئة متدرجة وتسمية نصية. يسمح الدمج بين 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("تدريج", 200f, 210f, textPaint)
    }
}

يستخدم الكود كائنين Paint منفصلين: واحد لملء الدائرة بتدريج شعاعي، والثاني للنص مع ظل عبر BlurMaskFilter. هذا الفصل يسمح بتكوين المعلمات بشكل مستقل وتجنب إعادة تعيين حالة Paint بين رسم أنواع مختلفة من العناصر. لتحسين الأداء، يتم إنشاء كلا كائني Paint في المنشئ، وليس في onDraw.

عند التحجيم على أجهزة بكثافات بكسل مختلفة، يجب إعادة حساب قيم الأحجام باستخدام TypedValue.applyDimension. دون ذلك، سيبدو النص والتدريجات بشكل مختلف على شاشات mdpi و xxxhdpi. في المثال، يتم تحديد حجم النص بوحدة sp، وهو ما يتكيف تلقائيًا مع إعدادات حجم خط النظام للمستخدم.

الأسئلة الشائعة

ما الفرق بين Paint و Canvas؟

Canvas يُنفّذ عمليات الرسم (drawCircle، drawLine)، بينما Paint يحدد النمط — اللون، السمك، الخط. Canvas لا يحتوي على إعدادات نمط، لذا دون Paint لا يكون لأي عملية رسم تأثير مرئي.

هل يمكن استخدام Paint واحد لأشكال مختلفة؟

نعم، يمكن إعادة استخدام كائن Paint واحد لعدة أشكال. يوصى بإنشاء كائنات Paint منفصلة لأنواع مختلفة من العناصر (الخلفية، النص، الحدود)، ولكن ليس لكل شكل — هذا يقلل الحمل على مجمع القمامة.

كيف أعيد تعيين Paint إلى الإعدادات الافتراضية؟

تعيد الطريقة reset Paint إلى حالة مكافئة لمثال جديد. بديلاً، يمكن استخدام set مع علامة، ولكن reset أفضل لقراءة الكود. بعد إعادة التعيين، تأخذ جميع معلمات النمط القيم الافتراضية.

هل يؤثر Paint على الأداء في onDraw؟

إنشاء Paint داخل onDraw يتسبب في تخصيص في كل إطار، مما يؤدي إلى تجمدات GC. يجب إنشاء جميع كائنات Paint في منشئ العرض. تغيير المعلمات في onDraw عبر المحددات آمن ولا ينشئ كائنات جديدة.

كيف أجعل خلفية النص شفافة في Paint؟

يتم رسم النص في Android دائمًا بخلفية شفافة. تطبع الطريقة drawText الرموز فقط، دون مستطيل خلفية. إذا كانت خلفية تحت النص مطلوبة، ارسم مستطيلاً أولاً باستخدام drawRoundRect مع Paint منفصل، ثم النص.

الملخص

  • Paint هو صف تهيئة لتنسيق الرسوميات على Canvas، يحدد اللون، السمك، الخط والتأثيرات.
  • setColor و setAlpha يتحكمان في اللون والشفافية بتكلفة إضافية إدني.
  • Style (FILL، STROKE، FILL_AND_STROKE) يحدد ما إذا يتم رسم حدود أو تعبئة أو كليهما.
  • Typeface و setTextSize يتعاملان مع الخطوط بدعم Downloadable Fonts والتكيف مع الشاشات.
  • Shader — LinearGradient، RadialGradient، BitmapShader — يضيف التدريجات والقوامش.
  • انشئ Paint في منشئ العرض، وليس في onDraw، لمنع تجمدات GC.
  • افصل Paint حسب نوع العنصر: تعبئة، حدود، نص — لتكوين مرن وقراءة محسنة للكود.

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا