onLayout(): تعریف، لے آؤٹ الگورتھم اور طریقہ کار کے پیرامیٹرز

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

onLayout() ViewGroup کلاس کا ایک طریقہ ہے جو پیرنٹ کنٹینر کے کوآرڈینیٹ پلین پر چائلڈ Views کی پوزیشنز اور سائز کا تعین کرتا ہے۔ Android سسٹم پیمائش کے مرحلے (onMeasure) کے بعد onLayout کو کال کرتا ہے، جب ہر چائلڈ View کے لیے ناپی گئی چوڑائی اور اونچائی پہلے سے معلوم ہوتی ہے۔ Android Developers Documentation (2026) کے مطابق، onLayout کسی بھی کسٹم ViewGroup میں اوور رائڈ کرنا لازمی ہے، کیونکہ معیاری ViewGroup نفاذ خودکار چائلڈ پوزیشننگ نہیں کرتا۔

اہم نکات

  • onLayout(boolean changed, int l, int t, int r, int b) — ViewGroup کا طریقہ جو پیرنٹ کوآرڈینیٹ میں چائلڈ عناصر کی پوزیشنز کا تعین کرتا ہے
  • child.layout(l, t, r, b) — ہر چائلڈ View کے لیے کال، اس کی حتمی حدود متعین کرتا ہے
  • لے آؤٹ مرحلہ View لائف سائیکل میں پیمائش کے مرحلے کے بعد اور ڈرا مرحلے سے پہلے آتا ہے
  • getWidth() اور getHeight() onLayout کے عملدرآمد کے بعد ہی دستیاب ہوتے ہیں، getMeasuredWidth کے برعکس جو onMeasure کے بعد دستیاب ہوتا ہے
  • requestLayout() — ایک طریقہ جو پوزیشننگ کو متاثر کرنے والے ڈیٹا میں تبدیلی پر onMeasure اور onLayout کی دوبارہ کال شروع کرتا ہے

onLayout() کیا ہے؟

onLayout(boolean changed, int l, int t, int r, int b) ViewGroup کلاس کا ایک protected طریقہ ہے جسے سسٹم پیرنٹ کنٹینر کے اندر چائلڈ Views کو پوزیشن دینے کے لیے کال کرتا ہے۔ ڈویلپر اس طریقہ کو اس وقت اوور رائڈ کرتا ہے جب وہ غیر معیاری عناصر کی ترتیب (جھرن، گرڈ، شطرنج پیٹرن یا صوابدیدی کوآرڈینیٹ) کے ساتھ کسٹم ViewGroup بناتا ہے۔ ہر چائلڈ View child.layout() کی کال کے ذریعے اپنی حتمی حدود حاصل کرتا ہے۔

changed پیرامیٹر اشارہ کرتا ہے کہ آخری لے آؤٹ کے بعد سے ViewGroup کی پوزیشن یا سائز تبدیل ہوئی ہے یا نہیں۔ اگر changed درست ہے تو، تمام چائلڈ عناصر کو ممکنہ طور پر دوبارہ پوزیشن دینے کی ضرورت ہے۔ پیرامیٹرز l, t, r, b اس کے پیرنٹ کے کوآرڈینیٹ سسٹم میں ViewGroup کے اوپر بائیں اور نیچے دائیں کونوں کے کوآرڈینیٹ ہیں۔ onLayout کے اندر، ڈویلپر ان اقدار کو چائلڈ کی ترتیب کے لیے ابتدائی کوآرڈینیٹ کے طور پر استعمال کرتا ہے۔

ViewGroup واحد کلاس ہے جو onLayout کو اوور رائڈ کرتی ہے۔ ایک عام View (ViewGroup نہیں) میں چائلڈ عناصر نہیں ہوتے اور اسے onLayout کی ضرورت نہیں ہوتی — اس کی پوزیشننگ پیرنٹ کنٹینر کے ذریعے سنبھالی جاتی ہے۔ یہاں تک کہ اگر کوئی عام View onLayout کو اوور رائڈ کرے، سسٹم اسے کال نہیں کرے گا۔ یہ onMeasure سے ایک بنیادی فرق ہے، جو کسی بھی View کے لیے کال کیا جاتا ہے۔

لے آؤٹ مرحلے کا بہاؤ

لے آؤٹ مرحلہ روٹ View پر عوامی طریقہ layout(int l, int t, int r, int b) کی کال سے شروع ہوتا ہے۔ یہ طریقہ View کے حتمی کوآرڈینیٹ متعین کرتا ہے اور اگر View ViewGroup ہے تو onLayout کو کال کرتا ہے۔ پھر onLayout ہر چائلڈ عنصر کے لیے بار بار child.layout() کال کرتا ہے، اور یہ عمل درجہ بندی میں نیچے کی طرف دہرایا جاتا ہے۔ اس طرح، لے آؤٹ جڑ سے پتوں تک پھیلتا ہے۔

onLayout کال کرنے سے پہلے، سسٹم چیک کرتا ہے کہ آیا پچھلے چکر کے مقابلے میں View کے طول و عرض تبدیل ہوئے ہیں۔ اگر طول و عرض تبدیل نہیں ہوئے اور requestLayout کال نہیں کیا گیا، تو onLayout کال نہیں کیا جا سکتا — سسٹم پچھلے لے آؤٹ کے نتائج استعمال کرتا ہے۔ یہ ایک اصلاح ہے جو اینیمیشن یا اسکرولنگ کے دوران غیر ضروری پوزیشن دوبارہ گنتی کو روکتی ہے، جب صرف مواد تبدیل ہوتا ہے نہ کہ طول و عرض۔

requestLayout() ایک View طریقہ ہے جو سسٹم کو مطلع کرتا ہے کہ View کا لے آؤٹ فرسودہ ہو گیا ہے اور اسے دوبارہ گنتی کی ضرورت ہے۔ requestLayout کال کرنا ایک مکمل چکر شروع کرتا ہے: پہلے onMeasure کال کیا جاتا ہے، پھر onLayout، پھر onDraw۔ invalidate کے برعکس، جو صرف دوبارہ ڈرائنگ کو متحرک کرتا ہے، requestLayout طول و عرض اور پوزیشنز کی مکمل دوبارہ گنتی کو متحرک کرتا ہے۔ requestLayout کے ضرورت سے زیادہ کالز کارکردگی کے مسائل کی ایک عام وجہ ہیں۔

onLayout کے پیرامیٹرز: l, t, r, b

l (left) — اس کے پیرنٹ کے کوآرڈینیٹ سسٹم میں ViewGroup کے بائیں کنارے کا X کوآرڈینیٹ۔ t (top) — اوپر والے کنارے کا Y کوآرڈینیٹ۔ r (right) — دائیں کنارے کا X کوآرڈینیٹ۔ b (bottom) — نیچے والے کنارے کا Y کوآرڈینیٹ۔ ViewGroup کی چوڑائی r - l کے طور پر، اونچائی b - t کے طور پر شمار کی جاتی ہے۔ یہ کوآرڈینیٹ پہلے سے ہی ViewGroup کے تمام پیڈنگ پر مشتمل ہوتے ہیں۔

onLayout کے اندر، ڈویلپر ہر چائلڈ View کے لیے child.layout(int childLeft, int childTop, int childRight, int childBottom) کال کرتا ہے۔ child.layout میں منتقل کردہ کوآرڈینیٹ پیرنٹ ViewGroup کے کوآرڈینیٹ سسٹم میں ہونے چاہئیں۔ عام طور پر childLeft اور childTop پیرنٹ کے پیڈنگ کو مدنظر رکھتے ہوئے شمار کیے جاتے ہیں: childLeft = l + paddingLeft + offsetX، childTop = t + paddingTop + offsetY۔

پیرامیٹرتفصیلعام استعمال
l (left)پیرنٹ میں ViewGroup کے بائیں کنارے کا کوآرڈینیٹچائلڈ عناصر کے لیے X محور پر نقطہ آغاز
t (top)پیرنٹ میں ViewGroup کے اوپری کنارے کا کوآرڈینیٹچائلڈ عناصر کے لیے Y محور پر نقطہ آغاز
r (right)پیرنٹ میں ViewGroup کے دائیں کنارے کا کوآرڈینیٹچوڑائی کی بالائی حد، r - l = getWidth()
b (bottom)پیرنٹ میں ViewGroup کے نچلے کنارے کا کوآرڈینیٹاونچائی کی بالائی حد، b - t = getHeight()

چائلڈ عناصر کے لیے کوآرڈینیٹ کا حساب

چائلڈ کوآرڈینیٹ فارمولے سے شمار کیے جاتے ہیں: childLeft = l + paddingLeft + (marginLeft اگر موجود ہو)، childRight = childLeft + child.getMeasuredWidth()۔ عمودی محور کے لیے بھی اسی طرح: childTop = t + paddingTop + (marginTop)، childBottom = childTop + child.getMeasuredHeight()۔ ان چار اقدار کا حساب لگانے کے بعد، child.layout(childLeft, childTop, childRight, childBottom) کال کیا جاتا ہے۔

Kotlin میں onLayout کے ساتھ کسٹم ViewGroup کی مثال

آئیے ایک FlowLayout بنائیں — ایک کسٹم ViewGroup جو چائلڈ Views کو قطاروں میں ترتیب دیتا ہے، جب موجودہ قطار بھر جائے تو عناصر کو نئی قطار میں منتقل کرتا ہے۔ یہ ایک ہی سطح میں wrap کے ساتھ Flexbox کا ہم منصب ہے۔ onLayout تمام چائلڈ Views کے ذریعے گردش کرتا ہے، ہر ایک کے لیے پوزیشن کا حساب لگاتا ہے اور درست حدود کے ساتھ child.layout() کال کرتا ہے۔

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

    private val horizontalSpacing = 12
    private val verticalSpacing = 8

    override fun onMeasure(widthMeasureSpec: Int,
                       heightMeasureSpec: Int) {
        val parentWidth =
            MeasureSpec.getSize(widthMeasureSpec)
        var rowX = paddingLeft
        var rowY = paddingTop
        var maxRowHeight = 0

        for (i in 0 until childCount) {
            val child = getChildAt(i)
            measureChildWithMargins(child,
                widthMeasureSpec, 0,
                heightMeasureSpec, 0)

            if (rowX + child.measuredWidth >
                parentWidth - paddingRight) {
                rowX = paddingLeft
                rowY += maxRowHeight + verticalSpacing
                maxRowHeight = 0
            }

            rowX += child.measuredWidth +
                horizontalSpacing
            maxRowHeight = maxOf(maxRowHeight,
                child.measuredHeight)
        }

        val totalHeight = rowY + maxRowHeight +
            paddingBottom
        setMeasuredDimension(
            resolveSize(parentWidth, widthMeasureSpec),
            resolveSize(totalHeight, heightMeasureSpec))
    }

    override fun onLayout(changed: Boolean,
                       l: Int, t: Int,
                       r: Int, b: Int) {
        val parentWidth = r - l
        var rowX = paddingLeft
        var rowY = paddingTop
        var maxRowHeight = 0

        for (i in 0 until childCount) {
            val child = getChildAt(i)
            val cw = child.measuredWidth
            val ch = child.measuredHeight

            if (rowX + cw >
                parentWidth - paddingRight) {
                rowX = paddingLeft
                rowY += maxRowHeight + verticalSpacing
                maxRowHeight = 0
            }

            child.layout(rowX, rowY,
                rowX + cw, rowY + ch)
            rowX += cw + horizontalSpacing
            maxRowHeight =
                maxOf(maxRowHeight, ch)
        }
    }

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

onLayout اور onMeasure کے درمیان فرق

onMeasure اور onLayout View لائف سائیکل کے دو متواتر مراحل ہیں جو بنیادی طور پر مختلف کام انجام دیتے ہیں۔ onMeasure View کے مطلوبہ (ناپے گئے) طول و عرض کا تعین کرتا ہے، جبکہ onLayout حقیقی (حتمی) کوآرڈینیٹ اور طول و عرض متعین کرتا ہے۔ کلیدی فرق: onMeasure میں، طول و عرض عارضی ہو سکتے ہیں اور بعد میں پیرنٹ کے ذریعے ایڈجسٹ کیے جا سکتے ہیں، جبکہ onLayout میں ہر چائلڈ View کی حتمی پوزیشن مقرر کی جاتی ہے۔

onMeasure ہر View کے لیے کال کیا جاتا ہے، بشمول لیف Views (TextView, ImageView, Button)۔ onLayout صرف ViewGroup کے لیے کال کیا جاتا ہے۔ اس کی وجہ یہ ہے کہ پوزیشننگ پیرنٹ کنٹینر کی ذمہ داری ہے، نہ کہ خود View کی۔ ایک لیف View پیرنٹ کے onLayout سے کال کردہ layout() کے ذریعے اپنی پوزیشن حاصل کرتا ہے۔

getMeasuredWidth() اور getMeasuredHeight() onMeasure کے بعد دستیاب ہوتے ہیں، جبکہ getWidth() اور getHeight() صرف onLayout کے بعد دستیاب ہوتے ہیں۔ اگر آپ onMeasure کے اندر getWidth() تک رسائی حاصل کرتے ہیں، تو یہ پچھلے چکر کی قدر یا صفر لوٹائے گا۔ لہذا، onMeasure میں طول و عرض کا حساب لگانے کے لیے، آپ کو MeasureSpec اور چائلڈ کو ترتیب وار استعمال کرنا چاہیے۔

onLayout کے ساتھ کام کرتے وقت عام غلطیاں

پیڈنگ کو مدنظر رکھے بغیر پوزیشننگ — onLayout کو نافذ کرتے وقت پہلی غلطی۔ ڈویلپر اکثر چائلڈ Views کے ابتدائی کوآرڈینیٹ میں پیرنٹ کا paddingLeft اور paddingTop شامل کرنا بھول جاتا ہے۔ نتیجے کے طور پر، چائلڈ ViewGroup کے کنارے پر ظاہر ہوتے ہیں، setPadding() یا XML مارک اپ کے ذریعے مقرر کردہ پیڈنگ کو نظر انداز کرتے ہوئے۔ درست حساب: childLeft = paddingLeft + offsetX۔

غیر مرئی چائلڈ کے لیے layout کال کرنا — دوسرا عام مسئلہ۔ اگر ViewGroup میں GONE نمائیت والے چائلڈ Views ہیں، تو انہیں پوزیشن دینے کی ضرورت نہیں ہے — وہ جگہ نہیں لیتے۔ تاہم، onLayout کو اس کیس کو صحیح طریقے سے سنبھالنا چاہیے، GONE چائلڈ کو چھوڑ کر۔ INVISIBLE چائلڈ کے لیے، layout کو پھر بھی کال کرنے کی ضرورت ہے — وہ ظاہر نہ ہونے کے باوجود اپنی جگہ برقرار رکھتے ہیں۔

changed پیرامیٹر کو نظر انداز کرنا — تیسری غلطی۔ changed پیرامیٹر اشارہ کرتا ہے کہ ViewGroup کے طول و عرض یا پوزیشن تبدیل ہوئی ہے یا نہیں۔ اگر changed == false ہے، تو تمام چائلڈ عناصر کے لے آؤٹ کو دوبارہ شمار کیے بغیر کیشڈ کوآرڈینیٹ استعمال کیے جا سکتے ہیں۔ تاہم، مکمل لے آؤٹ کیشنگ ایک پیچیدہ کام ہے، اور زیادہ تر نفاذ میں onLayout ہر بار صرف تمام عناصر کو دوبارہ شمار کرتا ہے۔ یہ کم تعداد میں چائلڈ کے ساتھ قابل قبول ہے۔

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

کیا ViewGroup میں onLayout کو اوور رائڈ نہ کرنا ممکن ہے؟

ہاں، ممکن ہے اگر ViewGroup معیاری LayoutParams استعمال کرے اور کسٹم پوزیشننگ منطق شامل نہ کرے۔ تاہم، ViewGroup میں onLayout کا معیاری نفاذ کوئی کارروائی نہیں کرتا — چائلڈ عناصر پوزیشن نہیں ہوں گے۔ عملی طور پر، تمام ViewGroup (LinearLayout, RelativeLayout, FrameLayout) onLayout کو اوور رائڈ کرتی ہیں۔

layout اور onLayout میں کیا فرق ہے؟

layout() View کا ایک عوامی حتمی طریقہ ہے، جسے سسٹم یا پیرنٹ ViewGroup کال کرتا ہے۔ یہ View کے کوآرڈینیٹ متعین کرتا ہے اور اگر View ViewGroup ہے تو onLayout کال کرتا ہے۔ onLayout() ایک protected طریقہ ہے جسے ڈویلپر چائلڈ عناصر کی کسٹم ترتیب کے لیے اوور رائڈ کرتا ہے۔

کیا onLayout requestLayout کال کر سکتا ہے؟

تکنیکی طور پر — ہاں، کر سکتا ہے۔ لیکن یہ سختی سے تجویز نہیں کیا جاتا، کیونکہ یہ لامحدود تکرار کا باعث بنتا ہے: requestLayout → onMeasure → onLayout → requestLayout۔ اگر onLayout کے اندر requestLayout کال کیا جاتا ہے، سسٹم StackOverflowError مستثنیٰ پھینکے گا۔ تمام طول و عرض تبدیلیاں onLayout سے پہلے کی جانی چاہئیں۔

onLayout اینیمیشن کے ساتھ کیسے کام کرتا ہے؟

لے آؤٹ اینیمیشن (LayoutTransition) چائلڈ View کی پوزیشنز میں تبدیلیوں کو روکتی ہیں اور منتقلی اینیمیشن کا اطلاق کرتی ہیں۔ جب LayoutTransition فعال ہوتا ہے، onLayout پہلے حتمی پوزیشنز متعین کرتا ہے، پھر LayoutTransition پرانی پوزیشن سے نئی پوزیشن میں حرکت کو اینیمیٹ کرتا ہے۔ اس کے لیے مناسب حتمی کوآرڈینیٹ کے ساتھ درست onLayout نفاذ کی ضرورت ہوتی ہے۔

invalidate کے بعد onLayout کیوں نہیں کال ہوتا؟

invalidate() صرف draw مرحلہ (دوبارہ ڈرائنگ) کو متحرک کرتا ہے، measure اور layout کو متاثر کیے بغیر۔ onLayout کو متحرک کرنے کے لیے، آپ کو requestLayout() کال کرنے کی ضرورت ہے، جو مکمل چکر شروع کرتا ہے: measure → layout → draw۔ invalidate ظاہری شکل کو اپ ڈیٹ کرنے کے لیے زیادہ موثر ہے جب طول و عرض اور پوزیشنز تبدیل نہیں ہوتیں۔

خلاصہ

  • onLayout() — ViewGroup کا طریقہ جو پیمائش کے مرحلے کی تکمیل کے بعد چائلڈ Views کی حتمی پوزیشنز کا تعین کرتا ہے
  • child.layout(l, t, r, b) — ہر چائلڈ عنصر کے لیے کوآرڈینیٹ متعین کرنے کا بنیادی طریقہ کار
  • پیرامیٹرز l, t, r, b — پیرنٹ سسٹم میں ViewGroup کے کناروں کے کوآرڈینیٹ، چوڑائی = r - l، اونچائی = b - t
  • لے آؤٹ مرحلہ روٹ View سے چائلڈ عناصر تک بار بار پھیلتا ہے، ہر ViewGroup پر onLayout کال کرتا ہے
  • requestLayout() طول و عرض اور پوزیشنز کی مکمل دوبارہ گنتی کا چکر شروع کرتا ہے، invalidate کے برعکس جو صرف دوبارہ ڈرائنگ شروع کرتا ہے
  • onLayout میں پیڈنگ کا خیال رکھنا لازمی ہے — چائلڈ کے ابتدائی کوآرڈینیٹ میں پیرنٹ کا paddingLeft اور paddingTop شامل ہونا چاہیے

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

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

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

مزید پڑھیں