dispatchDraw(): یہ کیا ہے، کال میکانزم اور onDraw سے فرق

مصنف: IT Sectr اشاعت: 2026-07-22 مطالعے کا وقت: 9 منٹ

dispatchDraw() ViewGroup کلاس کا ایک طریقہ ہے جو Android درجہ بندی میں تمام چائلڈ Views کی ریکرسیو ڈرائنگ کے لیے ذمہ دار ہے۔ Android Developers Documentation (2026) کے مطابق، dispatchDraw مرکزی View کے draw() طریقہ میں onDraw کے بعد خود بخود کال کیا جاتا ہے اور تمام چائلڈ عناصر کو عبور کرتا ہے، ان کے اپنے draw() کو کال کرتا ہے۔ ڈویلپر کسٹم ViewGroups میں dispatchDraw کو اوور رائڈ کرتے ہیں تاکہ اثرات شامل کریں، چائلڈز کے اوپر گرافکس لگائیں یا ڈرائنگ کی ترتیب تبدیل کریں۔

اہم نکات

  • dispatchDraw(Canvas canvas) ViewGroup کا ایک protected طریقہ ہے جو چائلڈ Views کو ڈرائنگ کرنے کے لیے onDraw کے بعد کال کیا جاتا ہے
  • draw(Canvas canvas) View کا ایک public final طریقہ ہے جو ترتیب وار onDraw، dispatchDraw اور onDrawForeground کو کال کرتا ہے
  • onDraw View کے اپنے مواد کو ڈرائنگ کرتا ہے، جبکہ dispatchDraw تمام چائلڈ عناصر کو ڈرائنگ کرتا ہے
  • setWillNotDraw(true) ان ViewGroups کے لیے ایک اصلاح ہے جو اپنا مواد نہیں ڈرائنگ کرتے، صرف چائلڈ عناصر ڈرائنگ کرتے ہیں
  • dispatchDraw کو اوور رائڈ کرنا اثرات (blur, overlay) لگانے یا چائلڈ ڈرائنگ کو متحرک کرنے کے لیے استعمال ہوتا ہے

dispatchDraw() کیا ہے؟

dispatchDraw(Canvas canvas) ViewGroup کلاس کا ایک protected طریقہ ہے جسے Android سسٹم موجودہ کنٹینر کے تمام چائلڈ Views کو ڈرائنگ کرنے کے لیے کال کرتا ہے۔ dispatchDraw معیاری ڈرائنگ پائپ لائن کا حصہ ہے: پہلے onDraw عمل میں آتا ہے (View کے اپنے مواد کی ڈرائنگ)، پھر dispatchDraw (چائلڈز کی ریکرسیو ڈرائنگ)، پھر onDrawForeground (پیش منظر اور اسکرول بار کی ڈرائنگ)۔ یہ طریقہ ایپلیکیشن کوڈ سے براہ راست کال کرنے کے لیے نہیں ہے۔

ViewGroup میں dispatchDraw کا معیاری نفاذ تمام چائلڈ Views کو عبور کرتا ہے، ان کی نمائش چیک کرتا ہے اور ہر ایک کے لیے draw(Canvas) کال کرتا ہے۔ عبور کرنے کی ترتیب چائلڈ انڈیکس (0 سے childCount - 1 تک) کے مطابق ہوتی ہے۔ اگر چائلڈ Views اوورلیپ ہوتے ہیں، تو فہرست میں بعد والے پہلے والوں کے اوپر ڈرائنگ ہوتے ہیں۔ dispatchDraw میں ترتیب تبدیل کرنے سے ڈرائنگ کا Z-order تبدیل کیا جا سکتا ہے۔

View (ViewGroup نہیں) کے لیے، dispatchDraw طریقہ خالی ہے — ایک عام View میں کوئی چائلڈ عناصر نہیں ہوتے، اس لیے ڈرائنگ کرنے کے لیے کچھ نہیں ہے۔ یہ طریقہ بیس View کلاس میں موجود ہے لیکن صرف ViewGroup مثالوں پر کال کیا جاتا ہے۔ ایک ڈویلپر dispatchDraw کے ڈیفالٹ رویے کے ذریعے چیک کر سکتا ہے کہ View میں چائلڈ عناصر ہیں یا نہیں، لیکن اکثر instanceof ViewGroup چیک کرنا آسان ہوتا ہے۔

ڈرائنگ پائپ لائن: onDraw, dispatchDraw, onDrawForeground

View کلاس کا draw(Canvas) طریقہ تین مراحل پر مشتمل ڈرائنگ پائپ لائن ترتیب دیتا ہے۔ پہلا مرحلہ onDraw(canvas) کال کرنا ہے، جہاں View اپنا مواد ڈرائنگ کرتا ہے۔ دوسرا مرحلہ dispatchDraw(canvas) کال کرنا ہے، جو چائلڈ Views کی ڈرائنگ شروع کرتا ہے۔ تیسرا مرحلہ onDrawForeground(canvas) ہے، جو پیش منظر کی تہہ، اسکرول بار اور ripple اثر کے لیے ذمہ دار ہے۔ یہ ترتیب گرافیکل تہوں کے صحیح اوورلے ترتیب کو یقینی بناتی ہے۔

onDraw ہمیشہ dispatchDraw سے پہلے عمل میں آتا ہے۔ اس کا مطلب ہے کہ پیرنٹ View کا مواد چائلڈ Views کے نیچے ظاہر ہوتا ہے۔ اگر آپ کو چائلڈز کے اوپر کچھ ڈرائنگ کرنے کی ضرورت ہے، تو یہ onDrawForeground میں یا اوور رائڈ شدہ dispatchDraw میں super.dispatchDraw(canvas) کال کرکے اور پھر اوپر ڈرائنگ کرکے کیا جاتا ہے۔ پس منظر onDraw سے پہلے بھی draw() طریقہ کے اندر drawBackground(canvas) میں ڈرائنگ کیا جاتا ہے۔

ہارڈویئر ایکسلریشن کے ساتھ، ڈرائنگ پائپ لائن GPU کے ذریعے کام کرتی ہے۔ View کو DisplayList میں ڈرائنگ کیا جاتا ہے — ڈرائنگ کمانڈز کی ایک فہرست جو کیش کی جاتی ہے اور دوبارہ استعمال ہوتی ہے۔ ہارڈویئر ایکسلریٹڈ موڈ میں dispatchDraw چائلڈ Views کے DisplayLists کو منظر کے مجموعی DisplayList میں شامل کرتا ہے۔ dispatchDraw میں ترمیم کرنے سے DisplayList باطل ہو سکتا ہے اور کیشے کی دوبارہ تعمیر ہو سکتی ہے، جو کارکردگی کو متاثر کرتی ہے۔

طریقہکال کی ترتیبمقصد
drawBackground1پس منظر کی ڈرائنگ (background drawable)
onDraw2View کے اپنے مواد کی ڈرائنگ
dispatchDraw3تمام چائلڈ Views کی ڈرائنگ (صرف ViewGroup)
onDrawForeground4پیش منظر، اسکرول بار اور ripple اثر کی ڈرائنگ

dispatchDraw اور onDraw میں فرق

onDraw View کے اپنے مواد — شکلیں، متن، تصاویر جو اس مخصوص عنصر سے تعلق رکھتی ہیں — کی ڈرائنگ کے لیے ذمہ دار ہے۔ dispatchDraw چائلڈ Views — ViewGroup کے اندر موجود تمام عناصر — کی ڈرائنگ کے لیے ذمہ دار ہے۔ اگر ViewGroup dispatchDraw کو اوور رائڈ نہیں کرتا، تو ViewGroup سے نفاذ استعمال ہوتا ہے، جو صرف childCount کو ریکرسیو طور پر عبور کرتا ہے اور ہر چائلڈ کے لیے draw کال کرتا ہے۔

ان ViewGroups کے لیے جو اپنا مواد ڈرائنگ نہیں کرتے (مثلاً FrameLayout, LinearLayout)، setWillNotDraw(true) سیٹ کرکے onDraw کو بہتر بنایا جا سکتا ہے۔ اس صورت میں، onDraw کبھی کال نہیں ہوتا، جو وسائل بچاتا ہے۔ dispatchDraw کام کرتا رہتا ہے اور چائلڈ عناصر کے لیے draw کال کرتا ہے۔ تمام معیاری ViewGroups (LinearLayout, RelativeLayout, ConstraintLayout) setWillNotDraw(true) استعمال کرتے ہیں۔

اگر آپ super.dispatchDraw(canvas) کال کیے بغیر dispatchDraw کو اوور رائڈ کرتے ہیں، تو چائلڈ Views ڈرائنگ نہیں ہوں گے۔ یہ تمام چائلڈز کو عارضی طور پر چھپانے کے لیے مفید ہو سکتا ہے، لیکن زیادہ تر معاملات میں یہ خرابیاں پیدا کرتا ہے۔ تجویز کردہ عمل: اوور رائڈ کردہ طریقہ کے شروع میں super.dispatchDraw(canvas) کال کریں، پھر چائلڈز کے اوپر اپنی گرافکس (مثلاً الفا چینل کے ساتھ اوورلے) شامل کریں۔

Kotlin میں dispatchDraw اوور رائڈ کرنے کی مثال

آئیے OverlayViewGroup بناتے ہیں — ایک کسٹم ViewGroup جو تمام چائلڈ Views کے اوپر ٹیکسٹ لیبل کے ساتھ ایک نیم شفاف تہہ شامل کرتا ہے۔ dispatchDraw پہلے super کال کرتا ہے (تمام چائلڈز کی ڈرائنگ)، پھر اوورلے مستطیل اور متن ڈرائنگ کرتا ہے۔ Paint کنسٹرکٹر میں بنایا جاتا ہے تاکہ ڈرائنگ لوپ میں مختص کرنے سے بچا جا سکے۔

kotlin
class OverlayViewGroup(context: Context)
    : ViewGroup(context) {

    private val overlayPaint = Paint().apply {
        color = Color.parseColor("#66000000")
        style = Paint.Style.FILL
    }

    private val textPaint = Paint().apply {
        color = Color.WHITE
        textSize = 36f
        isAntiAlias = true
        textAlign = Paint.Align.CENTER
    }

    init {
        setWillNotDraw(false)
    }

    override fun dispatchDraw(canvas: Canvas) {
        super.dispatchDraw(canvas)
        canvas.drawRect(0f, 0f,
                        width.toFloat(),
                        height.toFloat(), overlayPaint)
        canvas.drawText("پیش منظر موڈ",
            width / 2f,
            height / 2f, textPaint)
    }

    override fun onLayout(changed: Boolean,
                       l: Int, t: Int,
                       r: Int, b: Int) {
        var top = t
        for (i in 0 until childCount) {
            val child = getChildAt(i)
            val cw = child.measuredWidth
            val ch = child.measuredHeight
            child.layout(l, top, l + cw, top + ch)
            top += ch
        }
    }

    override fun onMeasure(widthMeasureSpec: Int,
                       heightMeasureSpec: Int) {
        measureChildren(widthMeasureSpec, heightMeasureSpec)
        val maxWidth = resolveSize(
            getChildAt(0).measuredWidth,
            widthMeasureSpec)
        var totalHeight = 0
        for (i in 0 until childCount) {
            totalHeight += getChildAt(i).measuredHeight
        }
        setMeasuredDimension(maxWidth,
            resolveSize(totalHeight, heightMeasureSpec))
    }
}

dispatchDraw کے ذریعے متحرک Z-order

مندرجہ ذیل مثال چائلڈ عناصر کی ڈرائنگ کی ترتیب تبدیل کرنے کو ظاہر کرتی ہے۔ CircularRevealLayout dispatchDraw کو اوور رائڈ کرتا ہے اور چائلڈز کو الٹی ترتیب میں ڈرائنگ کرتا ہے، ایک الٹا Z-order اثر پیدا کرتا ہے۔ حرکت پذیری کے لیے، متحرک offset قدر کی بنیاد پر ڈرائنگ انڈیکس کا ایک چکری نقل مکانی شامل کیا جاتا ہے۔

kotlin
class ReverseOrderLayout(context: Context)
    : ViewGroup(context) {

    private var reverse = false

    override fun dispatchDraw(canvas: Canvas) {
        if (!reverse) {
            super.dispatchDraw(canvas)
            return
        }
        for (i in childCount - 1 downTo 0) {
            val child = getChildAt(i)
            if (child.visibility == GONE) continue
            drawChild(canvas, child, getDrawingTime())
        }
    }

    fun toggleReverse() {
        reverse = !reverse
        invalidate()
    }

    override fun onLayout(changed: Boolean,
                       l: Int, t: Int,
                       r: Int, b: Int) {
        var left = l
        for (i in 0 until childCount) {
            val child = getChildAt(i)
            val cw = child.measuredWidth
            child.layout(left, t,
                left + cw, t + child.measuredHeight)
            left += cw
        }
    }

    override fun onMeasure(widthMeasureSpec: Int,
                       heightMeasureSpec: Int) {
        measureChildren(widthMeasureSpec, heightMeasureSpec)
        var totalWidth = 0
        for (i in 0 until childCount) {
            totalWidth += getChildAt(i).measuredWidth
        }
        setMeasuredDimension(
            resolveSize(totalWidth, widthMeasureSpec),
            resolveSize(getChildAt(0).measuredHeight,
                heightMeasureSpec))
    }
}

Android میں dispatchDraw کب استعمال کریں

dispatchDraw ان منظرناموں میں استعمال ہوتا ہے جہاں آپ کو ViewGroup کے اپنے مواد کو متاثر کیے بغیر چائلڈ Views کی ڈرائنگ کے عمل کو متاثر کرنے کی ضرورت ہوتی ہے۔ اہم منظرنامے: تمام چائلڈز کے اوپر ایک مشترکہ اثر (اوورلے، شیڈو، گریڈینٹ) لگانا؛ گہرائی کے اثرات پیدا کرنے کے لیے Z-order تبدیل کرنا؛ Canvas تبدیلیوں کے ذریعے چائلڈ عناصر کے ظاہر یا غائب ہونے کو متحرک کرنا۔

اگر آپ کو چائلڈ عناصر کے نیچے گرافکس لگانے کی ضرورت ہے (پس منظر کا اثر)، onDraw استعمال کریں — dispatchDraw اس کے بعد کال ہوتا ہے۔ اگر گرافکس چائلڈز کے اوپر ہونی چاہیے — پہلے super کال کرکے، پھر Canvas.draw استعمال کرکے dispatchDraw استعمال کریں۔ اگر آپ کو عالمی رنگ یا شفافیت کی تبدیلی کی ضرورت ہے، تو dispatchDraw میں چائلڈز کی ڈرائنگ کو لپیٹنے کے لیے canvas.saveLayerAlpha() استعمال کرنا آسان ہے۔

سفارش نہیں کی جاتی dispatchDraw استعمال کرنا: 1) ریئل ٹائم میں پیچیدہ حرکت پذیری ڈرائنگ کرنے کے لیے (invalidate اور onDraw استعمال کریں)؛ 2) ViewGroup کے اسکرین شاٹس بنانے کے لیے (buildDrawingCache() یا View.draw(Canvas) استعمال کریں)؛ 3) چائلڈ Views میں ترمیم کرنے کے لیے (متناسقات، سائز — یہ onLayout کے کام ہیں، dispatchDraw کے نہیں)۔ dispatchDraw صرف بصری اثرات لگانے کے لیے ہے۔

اکثر پوچھے گئے سوالات

کیا dispatchDraw کو سسٹم کے بغیر براہ راست کال کیا جا سکتا ہے؟

نہیں، dispatchDraw ایک protected طریقہ ہے جسے Android سسٹم عوامی draw() طریقہ کے اندر کال کرتا ہے۔ dispatchDraw کا براہ راست کال بے معنی ہے کیونکہ یہ تیاری کے اقدامات (Canvas محفوظ کرنا، پس منظر اور پیش منظر ڈرائنگ کرنا) انجام نہیں دیتا۔ اس کے بجائے، پروگراماتی طور پر کسی بھی Canvas پر ڈرائنگ کرنے کے لیے View.draw(Canvas) استعمال کریں۔

کسٹم ڈرائنگ کے بعد super.dispatchDraw کال کرنے سے کیا ہوتا ہے؟

اگر آپ اپنی ڈرائنگ کے عمل کے بعد super.dispatchDraw(canvas) کال کرتے ہیں، تو چائلڈ Views کسٹم گرافکس کے اوپر ڈرائنگ ہوں گے۔ یہ تہوں کی ترتیب کو تبدیل کرتا ہے: پہلے کسٹم تہہ ڈرائنگ ہوتی ہے، پھر چائلڈز۔ اگر آپ کو الٹی صورت حال کی ضرورت ہے (چائلڈز کے اوپر گرافکس)، پہلے super.dispatchDraw کال کریں، پھر اپنے عمل۔

dispatchDraw کارکردگی کو کیسے متاثر کرتا ہے؟

dispatchDraw ہر چائلڈ View کے لیے draw() کال کرتا ہے، اور کل وقت چائلڈز کی تعداد کے متناسب ہوتا ہے۔ ہارڈویئر ایکسلریشن کے ساتھ، dispatchDraw میں Canvas آپریشنز شامل کرنے سے DisplayList باطل ہو سکتا ہے اور کیشے کی دوبارہ تعمیر ہو سکتی ہے۔ 5–10 چائلڈز کے لیے اثر کم سے کم ہے، 50+ چائلڈز کے لیے پیچیدہ اوورلیز کو کیش کرنے کی سفارش کی جاتی ہے۔

View کے لیے dispatchDraw کیوں کال نہیں ہوتا؟

ایک View (ViewGroup نہیں) میں کوئی چائلڈ عناصر نہیں ہوتے، اس لیے dispatchDraw کوئی مفید کام انجام نہیں دیتا۔ تاہم، یہ طریقہ پولیمورفزم کے لیے بنیادی View کلاس میں موجود ہے: draw() میں کوڈ کسی بھی View کے لیے dispatchDraw کال کرتا ہے، لیکن View کے نفاذ میں چائلڈ ڈرائنگ کی منطق موجود نہیں ہے۔ صرف ViewGroup dispatchDraw کو اوور رائڈ کرتا ہے۔

کیا dispatchDraw میں Canvas تبدیل کیا جا سکتا ہے؟

ہاں، dispatchDraw ایک Canvas قبول کرتا ہے، اور super.dispatchDraw کال کرنے سے پہلے اسے تبدیل کیا جا سکتا ہے (translate, rotate, scale)۔ یہ چائلڈز کے پورے سیٹ کو ایک اکائی کے طور پر متحرک کرنے کے لیے استعمال ہوتا ہے۔ super.dispatchDraw مکمل ہونے کے بعد، Canvas کو اس کی اصل حالت میں بحال کرنے کی سفارش کی جاتی ہے۔

خلاصہ

  • dispatchDraw(Canvas) onDraw کے بعد تمام چائلڈ Views کی ریکرسیو ڈرائنگ کے لیے ViewGroup کا طریقہ ہے
  • ڈرائنگ پائپ لائن: drawBackground → onDraw → dispatchDraw → onDrawForeground
  • onDraw View کے اپنے مواد کو ڈرائنگ کرتا ہے، dispatchDraw چائلڈ عناصر کے مواد کو ڈرائنگ کرتا ہے
  • setWillNotDraw(true) onDraw کو چھوڑ کر ViewGroup کو بہتر بناتا ہے، لیکن dispatchDraw کام کرتا رہتا ہے
  • dispatchDraw کو اوور رائڈ کرنا اثرات لگانے، Z-order تبدیل کرنے اور چائلڈز کے Canvas تبدیلیوں کے لیے استعمال ہوتا ہے
  • super.dispatchDraw اور کسٹم ڈرائنگ کی ترتیب طے کرتی ہے کہ چائلڈز کے اوپر کیا ظاہر ہوگا
  • عام View (ViewGroup نہیں) کے لیے dispatchDraw خالی ہے — اس میں کوئی چائلڈ عناصر نہیں ہوتے

ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے

IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔

پروجیکٹ پر بحث کریں

مزید پڑھیں