dispatchDraw() ViewGroup क्लास का एक मेथड है जो Android पदानुक्रम में सभी चाइल्ड Views की रिकर्सिव ड्रॉइंग के लिए जिम्मेदार है। Android Developers Documentation (2026) के अनुसार, dispatchDraw मुख्य View के draw() मेथड में onDraw के बाद स्वचालित रूप से कॉल किया जाता है और सभी चाइल्ड एलिमेंट्स पर जाकर उनके स्वयं के draw() को कॉल करता है। डेवलपर कस्टम ViewGroups में इफेक्ट्स जोड़ने, चाइल्ड्स के ऊपर ग्राफिक्स लगाने या ड्रॉइंग ऑर्डर बदलने के लिए 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 जाँचना आसान होता है।
View क्लास का draw(Canvas) मेथड तीन-चरणीय ड्रॉइंग पाइपलाइन व्यवस्थित करता है। पहला चरण onDraw(canvas) कॉल करना है, जहाँ View अपनी सामग्री ड्रॉ करता है। दूसरा चरण dispatchDraw(canvas) कॉल करना है, जो चाइल्ड Views की ड्रॉइंग शुरू करता है। तीसरा चरण onDrawForeground(canvas) है, जो फोरग्राउंड लेयर, स्क्रॉलबार और रिपल इफेक्ट के लिए जिम्मेदार है। यह क्रम ग्राफिकल लेयर्स के सही ओवरले क्रम की गारंटी देता है।
onDraw हमेशा dispatchDraw से पहले निष्पादित होता है। इसका मतलब है कि पैरेंट View की सामग्री चाइल्ड Views के नीचे प्रदर्शित होती है। यदि आपको चाइल्ड्स के ऊपर कुछ ड्रॉ करना है, तो यह onDrawForeground में या ओवरराइड किए गए dispatchDraw में super.dispatchDraw(canvas) कॉल करके और फिर ऊपर ड्रॉ करके किया जाता है। बैकग्राउंड onDraw से पहले भी draw() मेथड के अंदर drawBackground(canvas) में ड्रॉ किया जाता है।
हार्डवेयर एक्सेलेरेशन के साथ, ड्रॉ पाइपलाइन GPU के माध्यम से काम करती है। View को DisplayList में ड्रॉ किया जाता है — ड्रॉ कमांड की एक सूची जो कैश की जाती है और पुनः उपयोग की जाती है। हार्डवेयर-एक्सेलरेटेड मोड में dispatchDraw चाइल्ड Views के DisplayLists को सीन के समग्र DisplayList में जोड़ता है। dispatchDraw को संशोधित करने से DisplayList अमान्य हो सकता है और कैश पुनर्निर्माण हो सकता है, जो प्रदर्शन को प्रभावित करता है।
| मेथड | कॉल क्रम | उद्देश्य |
|---|---|---|
| drawBackground | 1 | बैकग्राउंड ड्रॉ करना (background drawable) |
| onDraw | 2 | View की स्वयं की सामग्री ड्रॉ करना |
| dispatchDraw | 3 | सभी चाइल्ड Views ड्रॉ करना (केवल ViewGroup) |
| onDrawForeground | 4 | फोरग्राउंड, स्क्रॉलबार और रिपल इफेक्ट ड्रॉ करना |
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) कॉल करें, फिर चाइल्ड्स के ऊपर अपने ग्राफिक्स (जैसे अल्फा चैनल के साथ ओवरले) जोड़ें।
चलिए OverlayViewGroup बनाते हैं — एक कस्टम ViewGroup जो सभी चाइल्ड Views के ऊपर टेक्स्ट लेबल के साथ एक अर्ध-पारदर्शी परत जोड़ता है। dispatchDraw पहले super कॉल करता है (सभी चाइल्ड्स ड्रॉ करना), फिर ओवरले आयत और टेक्स्ट ड्रॉ करता है। Paint कंस्ट्रक्टर में बनाया जाता है ताकि ड्रॉ लूप में आवंटन से बचा जा सके।
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))
}
}
निम्नलिखित उदाहरण चाइल्ड एलिमेंट्स के ड्रॉइंग क्रम को बदलने को दर्शाता है। CircularRevealLayout dispatchDraw को ओवरराइड करता है और चाइल्ड्स को उल्टे क्रम में ड्रॉ करता है, जिससे उल्टा Z-order प्रभाव बनता है। एनिमेशन के लिए, एनिमेटेड offset मान के आधार पर ड्रॉइंग इंडेक्स का एक चक्रीय शिफ्ट जोड़ा जाता है।
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))
}
}
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 एक protected मेथड है जिसे Android सिस्टम सार्वजनिक draw() मेथड के अंदर कॉल करता है। dispatchDraw का सीधा कॉल अर्थहीन है क्योंकि यह तैयारी क्रियाएँ (Canvas सहेजना, बैकग्राउंड और फोरग्राउंड ड्रॉ करना) नहीं करता। इसके बजाय, प्रोग्रामेटिक रूप से किसी भी Canvas पर ड्रॉ करने के लिए View.draw(Canvas) का उपयोग करें।
यदि आप अपने स्वयं के ड्रॉइंग ऑपरेशन के बाद super.dispatchDraw(canvas) कॉल करते हैं, तो चाइल्ड Views कस्टम ग्राफिक्स के ऊपर ड्रॉ होंगे। यह लेयर क्रम बदलता है: पहले कस्टम लेयर ड्रॉ होती है, फिर चाइल्ड्स। यदि आपको विपरीत स्थिति चाहिए (चाइल्ड्स के ऊपर ग्राफिक्स), पहले super.dispatchDraw कॉल करें, फिर अपने ऑपरेशन।
dispatchDraw प्रत्येक चाइल्ड View के लिए draw() कॉल करता है, और कुल समय चाइल्ड्स की संख्या के अनुपात में होता है। हार्डवेयर एक्सेलेरेशन के साथ, dispatchDraw में Canvas ऑपरेशन जोड़ने से DisplayList अमान्य हो सकता है और कैश पुनर्निर्माण हो सकता है। 5–10 चाइल्ड्स के लिए प्रभाव न्यूनतम है, 50+ चाइल्ड्स के लिए जटिल ओवरले को कैश करने की अनुशंसा की जाती है।
एक View (ViewGroup नहीं) में कोई चाइल्ड एलिमेंट नहीं होते, इसलिए dispatchDraw कोई उपयोगी कार्य नहीं करता। हालाँकि, यह मेथड बेस View क्लास में पॉलीमॉर्फिज़्म के लिए मौजूद है: draw() में कोड किसी भी View के लिए dispatchDraw कॉल करता है, लेकिन View के कार्यान्वयन में चाइल्ड ड्रॉइंग लॉजिक नहीं होता। केवल ViewGroup dispatchDraw को ओवरराइड करता है।
हाँ, dispatchDraw एक Canvas स्वीकार करता है, और super.dispatchDraw कॉल करने से पहले इसे ट्रांसफॉर्म किया जा सकता है (translate, rotate, scale)। इसका उपयोग चाइल्ड्स के पूरे सेट को एक इकाई के रूप में एनिमेट करने के लिए किया जाता है। super.dispatchDraw पूरा होने के बाद, Canvas को उसकी मूल स्थिति में पुनर्स्थापित करने की अनुशंसा की जाती है।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें