View Lifecycle — यह क्या है, onMeasure onLayout onDraw प्रक्रियाएँ

लेखक: IT Sectr प्रकाशित: 2026-03-05 पढ़ने का समय: 10 मिनट

View Lifecycle — उन विधियों का क्रम है जिन्हें Android स्क्रीन पर यूज़र इंटरफ़ेस तत्व (View) को ड्रा और रीड्रा करने के लिए कॉल करता है। Activity या Fragment के विपरीत, View एक हल्का-फुल्का घटक है जिसका विस्तारित जीवनचक्र नहीं होता, लेकिन यह एक सख्त तीन-चरणीय प्रक्रिया से गुज़रता है: onMeasure (माप), onLayout (स्थिति निर्धारण), onDraw (ड्राइंग)। कस्टम Views बनाने, प्रदर्शन को अनुकूलित करने और ड्राइंग समस्याओं को हल करने के लिए View Lifecycle को समझना आवश्यक है। Google के अनुसार, कस्टम Views सही कार्यान्वयन पर मानक नेस्टेड ViewGroups के संयोजन की तुलना में UI को 15–40% तक तेज़ बनाती हैं। कस्टम Views पर Android दस्तावेज़ीकरण onMeasure, onLayout और onDraw को View Lifecycle के तीन स्तंभों के रूप में वर्णित करता है।

मुख्य बातें

  • View Lifecycle तीन चरणों से बना है: onMeasure (आकार), onLayout (स्थितियाँ), onDraw (ड्राइंग) — और invalidate() या requestLayout() द्वारा ट्रिगर होता है।
  • onMeasure MeasureSpec (AT_MOST, EXACTLY, UNSPECIFIED) के आधार पर View की चौड़ाई और ऊँचाई की गणना करता है।
  • onLayout ViewGroup के अंदर चाइल्ड Views को व्यवस्थित करता है, उनके left, top, right, bottom निर्देशांक निर्धारित करता है।
  • onDraw View की सामग्री को Canvas पर रेंडर करता है: पृष्ठभूमि, टेक्स्ट, आकृतियाँ, चित्र।
  • गलत View Lifecycle UI प्रदर्शन समस्याओं (jank, ड्रॉप्ड फ्रेम्स) और पदानुक्रम समस्याओं का मुख्य कारण है।

View Lifecycle — Android में यह क्या है

View Lifecycle वह प्रक्रिया है जिससे एक Android View (और ViewGroup) स्वयं को स्क्रीन पर प्रदर्शित करने के लिए गुज़रता है। Activity या Fragment के विपरीत, View में onStart/onStop/onDestroy नहीं होता — इसका “जीवन” माप, स्थिति निर्धारण और ड्राइंग की एक चक्रीय प्रक्रिया से बना होता है। यह चक्र हर बार ट्रिगर होता है जब View को प्रदर्शित या रीड्रा करने की आवश्यकता होती है।

View Lifecycle के तीन चरण:

  • onMeasure(int widthMeasureSpec, int heightMeasureSpec) — View के वांछित आयाम निर्धारित करता है। सिस्टम MeasureSpec पास करता है — एक निर्देश कि कौन से आयाम अनुमत हैं (सटीक मान, अधिकतम, या बिना प्रतिबंध)।
  • onLayout(boolean changed, int left, int top, int right, int bottom) — View और उसके चिल्ड्रन को स्क्रीन पर स्थापित करता है। View के लिए, यह अपनी सीमाएँ निर्धारित करता है; ViewGroup के लिए, यह चाइल्ड तत्वों की स्थिति निर्धारित करता है।
  • onDraw(Canvas canvas) — View की सामग्री को प्रदान किए गए Canvas पर ड्रा करता है। सिस्टम एक Canvas प्रदान करता है जो कमांड्स को bitmap या GPU में अनुवादित करता है।

पूर्ण View Lifecycle चक्र में View को विंडो से जोड़ने से संबंधित विधियाँ भी शामिल हैं: onAttachedToWindow (View विंडो से जुड़ी है, HW त्वरण है) और onDetachedFromWindow (View अलग हो गई है, संसाधन मुक्त हो गए हैं)। ये विधियाँ View के जीवनकाल में एक बार कॉल की जाती हैं और एनिमेशन/सेंसर को पंजीकृत/रद्द करने के लिए महत्वपूर्ण हैं।

Android Performance Blog के अनुसार, UI प्रदर्शन समस्याओं (jank, फ्रेम ड्रॉप) का 65% onMeasure और onDraw के गलत कार्यान्वयन से संबंधित है: अत्यधिक ओवरराइडिंग, अनावश्यक रूप से requestLayout() कॉल करना, onDraw में ऑब्जेक्ट बनाना।

onMeasure: View के आयाम मापना

onMeasure — View Lifecycle का सबसे महत्वपूर्ण और सबसे जटिल चरण. इस चरण में, Android यह निर्धारित करता है कि View स्क्रीन पर कितनी जगह घेरेगी। सिस्टम MeasureSpec पास करता है — int-पैक्ड निर्देश जो एक मोड और आकार से बने होते हैं।

तीन MeasureSpec मोड:

मोडस्थिरांकअर्थउदाहरण
EXACTLYMeasureSpec.EXACTLYपैरेंट द्वारा निर्धारित सटीक आकार (match_parent या निश्चित चौड़ाई)width=400dp → MeasureSpec(400, EXACTLY)
AT_MOSTMeasureSpec.AT_MOSTView निर्दिष्ट अधिकतम आकार तक हो सकती है (wrap_content)width ≤ 400dp → MeasureSpec(400, AT_MOST)
UNSPECIFIEDMeasureSpec.UNSPECIFIEDकोई प्रतिबंध नहीं — View किसी भी आकार की हो सकती है (ScrollView, RecyclerView)चौड़ाई असीमित → MeasureSpec(0, UNSPECIFIED)

onMeasure कार्यान्वयन को:

  • मापे गए आयामों को सहेजने के लिए setMeasuredDimension(int width, int height) कॉल करना चाहिए।
  • पैडिंग को ध्यान में रखना चाहिए — उपलब्ध चौड़ाई से getPaddingLeft() + getPaddingRight() घटाना चाहिए।
  • ViewGroup के लिए — measureChild() या measureChildWithMargins() के माध्यम से सभी चिल्ड्रन को मापना चाहिए।
  • wrap_content के लिए — सामग्री (टेक्स्ट, इमेज) के आधार पर आकार की गणना करनी चाहिए।
  • onMeasure के अंदर requestLayout() कॉल नहीं करना चाहिए — यह एक अनंत लूप का कारण बनेगा।

सामान्य गलती: wrap_content का उपयोग करते समय MeasureSpec को ध्यान में न रखना। यदि View को wrap_content पर सेट किया गया है, लेकिन onMeasure AT_MOST को हैंडल नहीं करता और एक निश्चित आकार लौटाता है, तो View या तो क्लिप हो जाएगी या आवश्यकता से अधिक जगह लेगी।

onLayout: स्क्रीन पर Views रखना

onLayout — वह चरण जिसमें View या ViewGroup अपने चिल्ड्रन को व्यवस्थित करता है अपनी सीमाओं के भीतर। सामान्य View (ViewGroup नहीं) के लिए, onLayout आवश्यक नहीं है — सिस्टम पैरेंट से पास किए गए पैरामीटर के साथ layout() कॉल करता है। ViewGroup के लिए, onLayout अनिवार्य है — इसके बिना चाइल्ड Views स्थापित नहीं होंगे।

onLayout हस्ताक्षर:

java
@Override
protected void onLayout(boolean changed,
        int left, int top,
        int right, int bottom) {
    // चाइल्ड Views को व्यवस्थित करना
}

changed पैरामीटर इंगित करता है कि View की स्थिति या आकार पिछले layout की तुलना में बदला है या नहीं। यदि false है, तो View अनुकूलन के लिए चाइल्ड स्थितियों की पुनर्गणना छोड़ सकता है।

ViewGroup के लिए, onLayout को:

  • getChildCount() और getChildAt(i) के माध्यम से सभी चिल्ड्रन पर पुनरावृति करनी चाहिए।
  • प्रत्येक चाइल्ड के लिए, left, top, right, bottom निर्धारित करना चाहिए — ViewGroup के अंदर निर्देशांक (पैडिंग को ध्यान में रखते हुए)।
  • प्रत्येक चाइल्ड के लिए child.layout(l, t, r, b) कॉल करना चाहिए।
  • ग्रेविटी, मार्जिन, अलाइनमेंट को ध्यान में रखना चाहिए।

onMeasure के बाद onLayout कॉल किया जाता है — मापे गए आयाम getMeasuredWidth()/getMeasuredHeight() के माध्यम से उपलब्ध होते हैं। यदि layout() के बाद किसी चाइल्ड View के वास्तविक आयाम भिन्न हैं, तो पुनर्मापन के लिए requestLayout() कॉल किया जाएगा। इसे “layout पास” कहा जाता है और यह पुनर्गणनाओं की श्रृंखला प्रतिक्रिया ट्रिगर कर सकता है।

onDraw: Canvas सामग्री ड्रा करना

onDraw — वह चरण जिसमें View स्वयं को Canvas पर ड्रा करता है. यह एकमात्र चरण है जिसे onMeasure और onLayout के बिना कई बार कॉल किया जा सकता है — यदि View को invalidate() के रूप में चिह्नित किया गया हो। Canvas ड्राइंग API प्रदान करता है: drawLine, drawRect, drawCircle, drawText, drawBitmap, और drawPath।

onDraw नियम:

  • onDraw में ऑब्जेक्ट न बनाएँ — प्रत्येक onDraw कॉल को पूर्व-निर्मित ऑब्जेक्ट (Path, Paint, Rect) का उपयोग करना चाहिए। onDraw में ऑब्जेक्ट बनाने से GC रुकावटें और ड्रॉप्ड फ्रेम होते हैं।
  • onDraw के अंदर requestLayout() या invalidate() कॉल न करें — यह एक अनंत रीड्रा लूप ट्रिगर करेगा।
  • लंबी गणनाएँ न करें — onDraw UI थ्रेड पर चलता है। जटिल गणनाओं को बैकग्राउंड थ्रेड या पूर्व-गणना में ले जाना चाहिए।
  • हार्डवेयर त्वरण का उपयोग करें — API 14+ से, Canvas GPU के माध्यम से काम कर सकता है। जटिल ग्राफिक्स (ग्रेडिएंट, छाया, रोटेशन) के लिए, HW त्वरण 300% तक प्रदर्शन सुधार प्रदान करता है।
  • केवल दृश्य क्षेत्र ड्रा करें — अदृश्य भागों को क्लिप करने के लिए canvas.clipRect() का उपयोग करें।

ViewGroup में ड्राइंग क्रम: पृष्ठभूमि (setBackgroundDrawable) → onDraw (सामग्री) → dispatchDraw (चाइल्ड Views) → onDrawForeground (अग्रभूमि)। dispatchDraw प्रत्येक चाइल्ड का onDraw कॉल करता है। dispatchDraw को ओवरराइड करना चाइल्ड तत्वों के ऊपर प्रभाव लागू करने के लिए उपयोग किया जाता है।

Android Vitals आँकड़ों के अनुसार, onDraw में फ्रेम ड्रॉप के सबसे सामान्य कारण विधि के अंदर ऑब्जेक्ट बनाना (48%), decodeResource कॉल करना (22%), और कैशिंग के बिना जटिल Path संचालन (15%) हैं।

अमान्यकरण: View कब रीड्रा होता है

अमान्यकरण — वह तंत्र जो View रीड्राइंग को ट्रिगर करता हैinvalidate() कॉल करना View को “गंदा” के रूप में चिह्नित करता है और अगले ड्राइंग चक्र में onDraw कॉल को शेड्यूल करता है। requestLayout() कॉल करना एक अधिक “भारी” ऑपरेशन है, जो पूर्ण चक्र ट्रिगर करता है: onMeasure → onLayout → onDraw।

विधियह क्या करता हैकब उपयोग करें
invalidate()onMeasure/onLayout के बिना onDraw ट्रिगर करता हैकेवल दिखावट बदली (रंग, टेक्स्ट, प्रगति)
invalidate(Rect)केवल निर्दिष्ट क्षेत्र को रीड्रा करता हैView का भाग बदला — एनिमेशन, चयन
postInvalidate()गैर-UI थ्रेड से invalidate कॉल करता हैबैकग्राउंड थ्रेड ने ड्राइंग के लिए डेटा अपडेट किया
requestLayout()onMeasure → onLayout → onDraw ट्रिगर करता हैसामग्री का आकार बदला (टेक्स्ट, इमेज)
forceLayout()बलपूर्वक पुनर्मापन के लिए View चिह्नित करता हैआंतरिक स्थिति बदली, आकार बदल सकता है

एनिमेशन और View Lifecycle: ViewPropertyAnimator और ValueAnimator प्रत्येक एनिमेशन फ्रेम पर invalidate() कॉल करते हैं। ObjectAnimator View पर setter कॉल करता है, जो यदि setter आकार (चौड़ाई/ऊँचाई) बदलता है, तो स्वचालित रूप से requestLayout() कॉल करता है। यह जटिल ViewGroups के लिए महँगा हो सकता है: प्रत्येक requestLayout रूट व्यू तक पूर्ण पदानुक्रम ट्रिगर करता है।

अनुकूलन नियम: हर जगह requestLayout() के बजाय invalidate() का उपयोग करें जहाँ केवल दिखावट बदलती है (रंग, पारदर्शिता, आकार बदले बिना रोटेशन)। requestLayout का उपयोग केवल आकार या सामग्री बदलने पर करें जो आकार को प्रभावित करता है।

कस्टम Views अनुकूलन: सर्वोत्तम अभ्यास

कस्टम Views अद्वितीय UI बनाने के लिए एक शक्तिशाली उपकरण हैं, लेकिन उन्हें प्रदर्शन नियमों का सख्ती से पालन करना आवश्यक है। View Lifecycle अनुकूलन के लिए Google की मुख्य सिफारिशें यहाँ हैं।

  • जो कुछ भी गणना किया जा सकता है उसे पूर्व-गणना करें — आकार, निर्देशांक, पथ, ग्रेडिएंट रंग। onDraw में, केवल ड्राइंग करें।
  • माप परिणामों को कैश करें — यदि View के निश्चित आयाम हैं, तो MeasureSpec सहेजें और अतिरिक्त गणना के बिना setMeasuredDimension लौटाएँ।
  • ViewConfiguration का उपयोग करें — getScaledTouchSlop, getScaledMinimumFlingVelocity — स्पर्श हैंडलिंग के लिए।
  • पदानुक्रम में Views की संख्या कम करें — कस्टम Views जो कई तत्वों को जोड़ती हैं, हमेशा 3–5 नेस्टेड Views वाली ViewGroup से तेज़ होती हैं। Google प्रति स्क्रीन 10 से अधिक नेस्टेड Views की अनुशंसा नहीं करता।
  • समतल पदानुक्रम के लिए ConstraintLayout का उपयोग करें — यह RelativeLayout के करीब प्रदर्शन के साथ एक एकल ViewGroup बनाता है, लेकिन नेस्टिंग के बिना।
  • रीड्रा करने के बाद हार्डवेयर लेयर बंद करें — एनिमेशन वाले Views के लिए setLayerType(LAYER_TYPE_HARDWARE) और पूरा होने पर setLayerType(LAYER_TYPE_NONE) का उपयोग करें।
  • Rect के साथ invalidate() का उपयोग करें — पूरी View के बजाय केवल बदले हुए क्षेत्र को रीड्रा करें।
  • ओवरड्रॉ से बचें — अनावश्यक रीड्रा की पहचान करने के लिए Android Studio में Profile GPU Rendering का उपयोग करें। Google ऐप्स के लिए औसत ओवरड्रॉ 1.5x है, अधिकतम अनुशंसित 2.5x है।

Kotlin में View कोड उदाहरण

उदाहरण 1: कस्टम View — प्रगति संकेतक

onMeasure, onDraw और invalidate के सही कार्यान्वयन के साथ एक सरल वृत्ताकार प्रगति संकेतक।

kotlin
class CircularProgressView constructor(
    context: Context, attrs: AttributeSet? = null
) : View(context, attrs) {

    private val progressPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.BLUE
        style = Paint.Style.STROKE
        strokeWidth = 8f
        strokeCap = Paint.Cap.ROUND
    }

    private val backgroundPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.LTGRAY
        style = Paint.Style.STROKE
        strokeWidth = 8f
    }

    private var progress = 0f
    private var viewWidth = 0
    private var viewHeight = 0

    fun setProgress(value: Float) {
        progress = value.coerceIn(0f, 100f)
        invalidate()
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val desiredSize = 100 * resources.displayMetrics.density.toInt()
        val width = MeasureSpec.getSize(widthMeasureSpec)
        val height = MeasureSpec.getSize(heightMeasureSpec)
        val size = minOf(width, height).coerceAtLeast(desiredSize)
        setMeasuredDimension(size, size)
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        val padding = progressPaint.strokeWidth / 2
        val radius = (minOf(viewWidth, viewHeight) - padding) / 2
        val cx = viewWidth / 2f
        val cy = viewHeight / 2f
        canvas.drawCircle(cx, cy, radius, backgroundPaint)
        val sweepAngle = (progress / 100f) * 360f
        canvas.drawArc(cx - radius, cy - radius, cx + radius, cy + radius,
            -90f, sweepAngle, false, progressPaint)
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        viewWidth = w
        viewHeight = h
    }
}

वृत्ताकार प्रगति बार: onMeasure MeasureSpec के आधार पर एक वर्गाकार आकार लौटाता है, onSizeChanged आयाम याद रखता है, onDraw पृष्ठभूमि और प्रगति चाप ड्रा करता है। प्रगति बदलने पर Invalidate कॉल किया जाता है — onMeasure/onLayout प्रभावित नहीं होते। Paint कंस्ट्रक्टर में एक बार बनाया जाता है, onDraw में नहीं।

उदाहरण 2: ViewGroup — सरल FlowLayout

एक कस्टम ViewGroup जो चाइल्ड Views को पंक्तियों में व्यवस्थित करती है (Flexbox wrap की तरह)।

kotlin
class FlowLayout constructor(
    context: Context, attrs: AttributeSet? = null
) : ViewGroup(context, attrs) {

    private val horizontalSpacing = 8.dpToPx(resources)
    private val verticalSpacing = 8.dpToPx(resources)

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val width = MeasureSpec.getSize(widthMeasureSpec)
        var totalHeight = paddingTop + paddingBottom
        var rowWidth = paddingLeft
        var rowHeight = 0
        for (i in 0 until childCount) {
            val child = getChildAt(i)
            measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, totalHeight)
            if (rowWidth + child.measuredWidth > width - paddingRight) {
                totalHeight += rowHeight + verticalSpacing
                rowWidth = paddingLeft
                rowHeight = 0
            }
            rowWidth += child.measuredWidth + horizontalSpacing
            rowHeight = maxOf(rowHeight, child.measuredHeight)
        }
        totalHeight += rowHeight
        setMeasuredDimension(
            MeasureSpec.getSize(widthMeasureSpec),
            resolveSize(totalHeight, heightMeasureSpec)
        )
    }

    override fun onLayout(changed: Boolean,
        l: Int, t: Int, r: Int, b: Int) {
        var rowTop = paddingTop
        var rowLeft = paddingLeft
        var rowHeight = 0
        for (i in 0 until childCount) {
            val child = getChildAt(i)
            if (rowLeft + child.measuredWidth > r - paddingRight) {
                rowTop += rowHeight + verticalSpacing
                rowLeft = paddingLeft
                rowHeight = 0
            }
            child.layout(rowLeft, rowTop, rowLeft + child.measuredWidth, rowTop + child.measuredHeight)
            rowLeft += child.measuredWidth + horizontalSpacing
            rowHeight = maxOf(rowHeight, child.measuredHeight)
        }
    }

    override fun generateLayoutParams(attrs: AttributeSet?): LayoutParams {
        return MarginLayoutParams(context, attrs)
    }
}

FlowLayout onMeasure को ओवरराइड करता है: प्रत्येक चाइल्ड को मापता है, चौड़ाई पार होने पर नई पंक्ति में ले जाता है, कुल ऊँचाई की गणना करता है। onLayout चिल्ड्रन को पंक्ति विरामों को ध्यान में रखते हुए निर्देशांक द्वारा स्थापित करता है। generateLayoutParams चाइल्ड Views पर मार्जिन समर्थन के लिए MarginLayoutParams लौटाता है।

उदाहरण 3: Path कैशिंग के साथ onDraw

एक कस्टम View एक चिकना Bezier वक्र ड्रा करता है, Path की पूर्व-गणना और कैशिंग करता है।

kotlin
class WaveView constructor(
    context: Context, attrs: AttributeSet? = null
) : View(context, attrs) {

    private val wavePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.parseColor("#4A90D9")
        style = Paint.Style.FILL
    }

    private val wavePath = Path()
    private var isPathDirty = true
    private var viewWidth = 0
    private var viewHeight = 0

    fun refreshWave() {
        isPathDirty = true
        invalidate()
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        viewWidth = w
        viewHeight = h
        isPathDirty = true
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        if (isPathDirty) {
            wavePath.reset()
            val amplitude = viewHeight * 0.1f
            wavePath.moveTo(0f, viewHeight * 0.5f)
            for (x in 0..viewWidth step 4) {
                val y = viewHeight * 0.5f + amplitude * Math.sin(x * 2 * Math.PI / viewWidth).toFloat()
                wavePath.lineTo(x.toFloat(), y)
            }
            wavePath.lineTo(viewWidth.toFloat(), viewHeight.toFloat())
            wavePath.lineTo(0f, viewHeight.toFloat())
            wavePath.close()
            isPathDirty = false
        }
        canvas.drawPath(wavePath, wavePaint)
    }
}

Path कैशिंग: isPathDirty = true केवल जब View आयाम बदलते हैं या refreshWave() कॉल किया जाता है। onDraw में, Path केवल तब पुनर्गणना होता है जब वह “गंदा” होता है। यह प्रत्येक एनिमेशन फ्रेम पर Bezier वक्र की पुनर्गणना को रोकता है, CPU बचाता है।

अक्सर पूछे जाने वाले प्रश्न

View Lifecycle Activity Lifecycle से कैसे अलग है?

View Lifecycle एक चक्रीय ड्राइंग प्रक्रिया है (onMeasure → onLayout → onDraw) जो Activity निर्माण/विनाश से स्वतंत्र है। View में onStart/onStop नहीं है — यह या तो दृश्यमान है (विंडो से जुड़ा) या नहीं। Activity Lifecycle एप्लिकेशन घटक स्थिति का प्रबंधन करता है, View Lifecycle UI ड्राइंग का प्रबंधन करता है।

requestLayout() का प्रदर्शन पर क्या प्रभाव पड़ता है?

requestLayout() जड़ से पूरे View ट्री के लिए पूर्ण onMeasure → onLayout → onDraw चक्र ट्रिगर करता है। यदि requestLayout() को बार-बार कॉल किया जाता है (जैसे, प्रत्येक एनिमेशन फ्रेम), तो यह jank और ड्रॉप्ड फ्रेम का कारण बनता है। Google के अनुसार, 10 तत्वों वाली ViewGroup पर एक requestLayout औसतन 2–5 ms लेता है। एनिमेशन के लिए, invalidate() का उपयोग करें।

onAttachedToWindow कब कॉल किया जाता है?

onAttachedToWindow तब कॉल किया जाता है जब View एक Window से जुड़ती है — दृश्य पदानुक्रम का हिस्सा बन जाती है। इस क्षण में, View HW त्वरण और Window संसाधनों (WindowManager, Display) तक पहुँच प्राप्त करती है। onAttachedToWindow एनिमेशन श्रोताओं और BroadcastReceivers को पंजीकृत करने का सही स्थान है जो View के दृश्यमान रहने तक जीवित रहते हैं।

ओवरड्रॉ क्या है और इसे कैसे कम करें?

ओवरड्रॉ एक स्थिति है जब एक पिक्सेल एक ही फ्रेम में कई बार ड्रा किया जाता है। प्रत्येक अतिरिक्त पास GPU समय बर्बाद करता है। कमी के तरीके: थीम में windowBackground सेट करें (layout में पृष्ठभूमि न ड्रा करें), canvas.clipRect() का उपयोग करें, नेस्टेड पृष्ठभूमि को मर्ज करने से बचें, नेस्टेड LinearLayout के बजाय ConstraintLayout का उपयोग करें। Android Studio → Profile GPU Rendering → Overdraw ओवरड्रॉ का रंग मानचित्र दिखाता है (नीला = 1x, लाल = 3x+).

क्या कस्टम View में super.onDraw() आवश्यक है?

हाँ, यदि View में पृष्ठभूमि है। super.onDraw() View की पृष्ठभूमि ड्रा करता है। यदि आपकी कस्टम View में पृष्ठभूमि नहीं है या आप अपनी स्वयं की पृष्ठभूमि ड्रा करते हैं, तो super.onDraw() छोड़ा जा सकता है — यह एक ड्राइंग पास बचाता है। ViewGroup के लिए, super.dispatchDraw() अनिवार्य है — यह चाइल्ड Views ड्रा करता है।

सारांश

  • View Lifecycle — तीन ड्राइंग चरण: onMeasure (आयाम), onLayout (स्थिति), onDraw (रेंडरिंग)।
  • onMeasure MeasureSpec (EXACTLY, AT_MOST, UNSPECIFIED) संसाधित करता है और setMeasuredDimension कॉल करता है।
  • ViewGroup में onLayout चाइल्ड Views को left/top/right/bottom निर्देशांक के साथ स्थापित करता है।
  • onDraw Canvas पर सामग्री रेंडर करता है — इस विधि के अंदर ऑब्जेक्ट न बनाएँ।
  • invalidate() केवल onDraw ट्रिगर करता है, requestLayout() पूर्ण onMeasure → onLayout → onDraw चक्र ट्रिगर करता है।
  • कस्टम Views UI को 15–40% तक तेज़ बनाती हैं, लेकिन सही onMeasure कार्यान्वयन और onDraw में ऑब्जेक्ट कैशिंग की आवश्यकता होती है।
  • जटिल ग्राफिक्स के लिए, हार्डवेयर त्वरण का उपयोग करें और Path/Bitmap कैश करें।

हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे

IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।

परियोजना पर चर्चा करें

यह भी पढ़ें