onMeasure(): یہ کیا ہے، MeasureSpec موڈز اور طریقہ کو اوور رائڈ کرنا

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

onMeasure() android.view.View کلاس کا ایک protected طریقہ ہے جسے Android سسٹم View کے سائز کا تعین کرنے کے لیے کال کرتا ہے۔ سسٹم اس طریقہ میں دو MeasureSpec آبجیکٹ بھیجتا ہے، جن میں سے ہر ایک میں پیمائش کا موڈ (EXACTLY، AT_MOST یا UNSPECIFIED) اور پیرنٹ کنٹینر کے تجویز کردہ سائز شامل ہوتا ہے۔ Android Developers Documentation (2026) کے مطابق، درست MeasureSpec ہینڈلنگ کے ساتھ onMeasure کو اوور رائڈ کرنا ان تمام کسٹم View اور ViewGroup کے لیے لازمی ہے جنہیں سائز پر عین مطابق کنٹرول کی ضرورت ہوتی ہے۔

اہم نکات

  • onMeasure(int widthMeasureSpec, int heightMeasureSpec) — پیرنٹ سے MeasureSpec حاصل کرکے سائز ناپنے کا View طریقہ
  • MeasureSpec — ایک 32 بٹ قدر جو پیمائش کے موڈ (UNSPECIFIED, EXACTLY, AT_MOST) اور سائز کو انکوڈ کرتی ہے
  • setMeasuredDimension(int w, int h) — onMeasure کے اندر لازمی کال جو View کے حتمی طول و عرض مقرر کرتی ہے
  • دو پاس الگورتھم پیمائش کے لیے: پیرنٹ بچوں کو ناپتا ہے، پھر بچے اپنے سائز بتاتے ہیں، اور پیرنٹ حتمی فیصلہ کرتا ہے
  • measureChildWithMargins — کسٹم ViewGroup میں چائلڈ View ناپنے کے لیے معاون طریقہ

onMeasure() کیا ہے؟

onMeasure(int widthMeasureSpec, int heightMeasureSpec) View کلاس کا ایک طریقہ ہے جسے Android سسٹم کسی ویو کی چوڑائی اور اونچائی کا تعین کرنے کے لیے کال کرتا ہے۔ ڈیولپر اس طریقہ کو اوور رائڈ کرکے یہ بتاتا ہے کہ MeasureSpec میں دی گئی رکاوٹوں کی بنیاد پر View کا سائز کیا ہونا چاہیے۔ درست onMeasure اوور رائڈنگ کے بغیر، کسٹم View غلط طریقے سے ظاہر ہو سکتا ہے یا بالکل نظر نہیں آ سکتا۔

سسٹم View کی زندگی کے چکر کے measure مرحلے کے دوران onMeasure کو کال کرتا ہے، جو layout (onLayout) اور draw (onDraw) مراحل سے پہلے آتا ہے۔ اگر کوئی View onMeasure کو اوور رائڈ نہیں کرتا، تو سپر کلاس کا نفاذ استعمال ہوتا ہے، جو background drawable یا layout_params کی بنیاد پر ڈیفالٹ سائز مقرر کرتا ہے۔ super.onMeasure(widthMeasureSpec, heightMeasureSpec) کو کال کرنا صرف View کے معیاری ذیلی طبقات جیسے TextView یا ImageView کے لیے کام کرتا ہے۔

onMeasure کے لیے ایک اہم ضرورت یہ ہے کہ setMeasuredDimension(int, int) کی کال طریقہ کے آخر میں موجود ہو۔ اگر یہ کال غائب ہے، تو سسٹم IllegalStateException پھینکتا ہے جس میں بتایا جاتا ہے کہ View نے ناپے گئے طول و عرض مقرر نہیں کیے۔ پیمائش کا مرحلہ مکمل ہونے کے بعد حتمی طول و عرض getMeasuredWidth() اور getMeasuredHeight() گیٹرز کے ذریعے دستیاب ہوتے ہیں۔

MeasureSpec موڈز: تین اہم قدریں

MeasureSpec ایک 32 بٹ عدد ہے جہاں اوپر کے 2 بٹ پیمائش کے موڈ کو انکوڈ کرتے ہیں اور نیچے کے 30 بٹ سائز کو انکوڈ کرتے ہیں۔ موڈ اس بات کا تعین کرتا ہے کہ View اپنا سائز منتخب کرنے میں کتنا آزاد ہے۔ Android تین موڈ فراہم کرتا ہے: EXACTLY، AT_MOST اور UNSPECIFIED۔ ہر موڈ onMeasure میں مختلف پروسیسنگ منطق کا حکم دیتا ہے۔

MeasureSpec موڈقدرسلوک
EXACTLYپیرنٹ نے عین مطابق سائز بتایاView کو دیے گئے سائز میں بالکل فٹ ہونا چاہیے اگر وہ حدوں سے باہر نہیں جانا چاہتا
AT_MOSTپیرنٹ نے زیادہ سے زیادہ سائز مقرر کیاView 0 سے دیے گئے زیادہ سے زیادہ تک کوئی بھی سائز منتخب کر سکتا ہے
UNSPECIFIEDپیرنٹ کوئی پابندی نہیں لگاتاView بغیر کسی بالائی حد کے کوئی بھی مطلوبہ سائز منتخب کر سکتا ہے

MeasureSpec سے موڈ اور سائز نکالنے کے لیے MeasureSpec کلاس کے جامد طریقے استعمال کیے جاتے ہیں: MeasureSpec.getMode(int) تین موڈز میں سے ایک واپس کرتا ہے (EXACTLY, AT_MOST, UNSPECIFIED)، اور MeasureSpec.getSize(int) پکسلز میں عددی سائز واپس کرتا ہے۔ کسٹم MeasureSpec بنانے کے لیے MeasureSpec.makeMeasureSpec(int size, int mode) استعمال کیا جاتا ہے۔ یہ تینوں طریقے onMeasure میں سائز کے ساتھ کام کرنے کے تمام منظرناموں کو کور کرتے ہیں۔

MeasureSpec ہینڈلنگ کی عام منطق

معیاری نمونہ MeasureSpec ہینڈلنگ کے لیے: اگر موڈ EXACTLY ہے — دیے گئے سائز کو حتمی کے طور پر استعمال کریں؛ اگر AT_MOST ہے — مطلوبہ سائز (View کا مواد) اور دیے گئے زیادہ سے زیادہ کے درمیان کم از کم منتخب کریں؛ اگر UNSPECIFIED ہے — بغیر کسی پابندی کے View کا مطلوبہ سائز استعمال کریں۔ یہ نمونہ پیرنٹ کی کسی بھی رکاوٹ کے تحت درست سلوک کو یقینی بناتا ہے۔

kotlin
override fun onMeasure(widthMeasureSpec: Int,
                       heightMeasureSpec: Int) {
    val desiredWidth = 200
    val desiredHeight = 100

    val widthMode = MeasureSpec.getMode(widthMeasureSpec)
    val widthSize = MeasureSpec.getSize(widthMeasureSpec)
    val heightMode = MeasureSpec.getMode(heightMeasureSpec)
    val heightSize = MeasureSpec.getSize(heightMeasureSpec)

    val width = when (widthMode) {
        MeasureSpec.EXACTLY -> widthSize
        MeasureSpec.AT_MOST -> minOf(desiredWidth, widthSize)
        else -> desiredWidth
    }
    val height = when (heightMode) {
        MeasureSpec.EXACTLY -> heightSize
        MeasureSpec.AT_MOST -> minOf(desiredHeight, heightSize)
        else -> desiredHeight
    }
    setMeasuredDimension(width, height)
}

resolveSize کا استعمال

معیاری منطق کو آسان بنانے کے لیے، Android resolveSizeAndState طریقہ فراہم کرتا ہے، جو مطلوبہ سائز اور MeasureSpec لے کر درست موڈ کے ساتھ حتمی سائز واپس کرتا ہے۔ یہ طریقہ اوپر بیان کردہ نمونے کو کوڈ کی ایک لائن میں نافذ کرتا ہے۔ resolveSize(int size, int measureSpec) فنکشن بھی دستیاب ہے، جو سٹیٹ بٹس کے بغیر صاف سائز واپس کرتا ہے۔

دو پاس پیمائش الگورتھم

Android دو پاس پیمائش الگورتھم استعمال کرتا ہے جو اس بات کو یقینی بناتا ہے کہ درجہ بندی میں ہر View کو پیرنٹ کی رکاوٹوں اور بچوں کی ترجیحات کو مدنظر رکھتے ہوئے درست طول و عرض ملے۔ پہلے پاس میں، پیرنٹ رکاوٹوں کے ساتھ MeasureSpec چائلڈ View کو بھیجتا ہے، اور چائلڈ View اپنے مطلوبہ سائز کا حساب لگاتے ہیں۔ دوسرے پاس میں، پیرنٹ سائز کے بارے میں حتمی فیصلہ کرتا ہے۔

ViewGroup کے لیے، پیمائش کا عمل زیادہ پیچیدہ ہے: پیرنٹ کو پہلے اپنے تمام بچوں کو ناپنا چاہیے، پھر ان کے سائز کی بنیاد پر اپنا سائز متعین کرنا چاہیے۔ measureChildren(int widthMeasureSpec, int heightMeasureSpec) کو کال کرنا تمام چائلڈ View کو iterate کرتا ہے اور ہر ایک کے لیے measure(child, childWidthSpec, childHeightSpec) کو کال کرتا ہے۔ تمام بچوں کو ناپنے کے بعد، ViewGroup اپنے طول و عرض کے ساتھ setMeasuredDimension کو کال کرتا ہے۔

ایک اہم باریکی: measure طریقہ (عوامی، حتمی) کو اوور رائڈ نہیں کیا جا سکتا — اس کے بجائے onMeasure کو اوور رائڈ کیا جاتا ہے۔ یہ اس بات کو یقینی بناتا ہے کہ سسٹم onMeasure سے پہلے اور بعد میں دیکھ بھال کے کام انجام دے سکتا ہے، جیسے سائز میں تبدیلی کی جانچ کرنا اور بعد میں ڈرائنگ کے لیے گندے علاقے کا حساب لگانا۔ اگر View کے مقررہ طول و عرض ہیں، تو onMeasure کو اوور رائڈ کرنا ضروری نہیں ہو سکتا۔

MEASURED_SIZE_STATE پرچم

MeasureSpec میں نہ صرف سائز اور موڈ بلکہ سٹیٹ بٹس بھی شامل ہیں، جو MeasureSpec.getMode() کے ذریعے قابل رسائی ہیں۔ setMeasuredDimension کو کال کرنے کے بعد، حالت View کے ناپے گئے طول و عرض کا حصہ بن جاتی ہے اور getMeasuredState() کے ذریعے جانچی جا سکتی ہے۔ یہ ScrollView اور دیگر اسکرول ایبل کنٹینرز میں بچوں تک رکاوٹوں کو صحیح طریقے سے پہنچانے کے لیے استعمال ہوتا ہے۔

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

آئیے مربع ڈسپلے کے لیے onMeasure کے ساتھ ایک کسٹم View بنانے کی عملی مثال دیکھتے ہیں۔ SquareView کلاس View کو بڑھاتی ہے اور اس بات کو یقینی بناتی ہے کہ چوڑائی اور اونچائی ہمیشہ برابر ہوں، بھیجے گئے MeasureSpec سے قطع نظر۔ onMeasure میں، کم از کم پہلو کا تعین کیا جاتا ہے اور مربع سائز مقرر کیا جاتا ہے۔

kotlin
class SquareView(context: Context)
    : View(context) {

    override fun onMeasure(widthMeasureSpec: Int,
                       heightMeasureSpec: Int) {
        val widthSize =
            MeasureSpec.getSize(widthMeasureSpec)
        val heightSize =
            MeasureSpec.getSize(heightMeasureSpec)
        val size = minOf(widthSize, heightSize)
        setMeasuredDimension(size, size)
    }
}

بچوں کی پیمائش کے ساتھ کسٹم ViewGroup

ViewGroup کو زیادہ پیچیدہ onMeasure منطق کی ضرورت ہوتی ہے کیونکہ پہلے بچوں کو ناپنا ضروری ہے، پھر ViewGroup کا اپنا سائز متعین کیا جاتا ہے۔ CascadeLayout مثال بچوں کو ایک آفسیٹ کے ساتھ جھرن میں تقسیم کرتی ہے۔ measureChildWithMargins کے ذریعے تمام بچوں کو ناپنے کے بعد، کل چوڑائی اور اونچائی کا حساب لگایا جاتا ہے۔

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

    private val cascadeOffset = 40

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

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

    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 left = l + cascadeOffset * i
            child.layout(left, top,
                left + child.measuredWidth,
                top + child.measuredHeight)
            top += child.measuredHeight
        }
    }
}

onMeasure اوور رائڈ کرتے وقت عام غلطیاں

setMeasuredDimension کال چھوڑنا سب سے عام غلطی ہے۔ اگر ڈیولپر onMeasure کو اوور رائڈ کرتا ہے لیکن setMeasuredDimension کو کال نہیں کرتا، تو ایپلیکیشن IllegalStateException کے ساتھ کریش ہو جاتی ہے۔ یہ خاص طور پر اس وقت ہوتا ہے جب طریقہ میں مشروط شاخیں ہوں اور ایک شاخ میں کال غائب ہو۔ onMeasure میں کوڈ کی ہر شاخ setMeasuredDimension کال کے ساتھ ختم ہونی چاہیے۔

AT_MOST موڈ کو نظر انداز کرنا دوسری سب سے عام غلطی ہے۔ اگر AT_MOST موڈ میں کوئی View مواد کی بنیاد پر حساب کرنے کے بجائے ہمیشہ بھیجا گیا سائز استعمال کرتا ہے، تو پیرنٹ کنٹینر جگہ کو صحیح طریقے سے تقسیم نہیں کر سکتا۔ مثال کے طور پر، AT_MOST میں TextView کو متن کی چوڑائی کا حساب لگانا چاہیے اور مطلوبہ اور بھیجی گئی چوڑائی میں سے کم از کم استعمال کرنی چاہیے۔ AT_MOST کو نظر انداز کرنے سے View چھوٹے مواد کے باوجود تمام دستیاب جگہ گھیر لیتا ہے۔

onMeasure کے اندر آبجیکٹ بنانا ایک کلاسک کارکردگی کی غلطی ہے۔ چونکہ onMeasure متعدد بار کال کیا جا سکتا ہے (ہر layout درخواست پر)، اس طریقہ کے اندر آبجیکٹ (Paint, Rect, String) بنانا میموری کو خراب کرتا ہے اور کوڑا اکٹھا کرنے کو متحرک کرتا ہے۔ تمام آبجیکٹ View کنسٹرکٹر میں ایک بار بنائے جائیں، اور onMeasure میں صرف سائز کے حساب کی منطق چلنی چاہیے۔ یہی اصول onDraw اور onLayout پر بھی لاگو ہوتا ہے۔

ViewGroup میں چائلڈ View ناپنا

measureChildWithMargins ViewGroup کا ایک محفوظ طریقہ ہے جو ایک واحد چائلڈ View کو اس کے MarginLayoutParams کو مدنظر رکھتے ہوئے ناپتا ہے۔ طریقہ پیرنٹ کا MeasureSpec اور جمع شدہ چوڑائی اور اونچائی کے آفسیٹ قبول کرتا ہے۔ یہ پیرنٹ کے padding اور چائلڈ کے margin کو گھٹا کر چائلڈ View کے لیے MeasureSpec کو خود بخود ایڈجسٹ کرتا ہے، پھر ایڈجسٹ شدہ MeasureSpec کو child.measure() میں بھیجتا ہے۔

اعلی درجے کی پیمائش منطق کے لیے، ViewGroup measureChild(View child, int parentWidthSpec, int parentHeightSpec) کو اوور رائڈ کر سکتا ہے یا ہر بچے کے لیے براہ راست MeasureSpec کے ساتھ کام کر سکتا ہے۔ مثال کے طور پر، LinearLayout onMeasure میں تمام چائلڈ View کو iterate کرتا ہے، ہر ایک کو اس کے layout_weight کو مدنظر رکھتے ہوئے ناپتا ہے اور باقی جگہ کو متناسب طور پر تقسیم کرتا ہے۔ یہ طریقہ صوابدیدی layout الگورتھم کو نافذ کرنے کی اجازت دیتا ہے۔

پیمائش کے نتائج کو پیمائش کیش میکانزم کے ذریعے کیش کرنا مخصوص ViewGroup میں setMeasureWithLargestChildEnabled پرچم کے ذریعے دستیاب ہے۔ تاہم، زیادہ تر معاملات میں onMeasure کسی بھی layout تبدیلی پر دوبارہ کال کیا جاتا ہے اور کیشنگ لاگو نہیں ہوتی۔ کسٹم ViewGroup میں، کیشنگ پر انحصار کرنے کے بجائے onMeasure میں حسابات کو کم سے کم کرنے کی سفارش کی جاتی ہے۔

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

کیا کسٹم View کے لیے onMeasure کو اوور رائڈ کرنا ضروری ہے؟

ہاں، اگر کسٹم View براہ راست View کلاس سے وراثت پاتا ہے۔ اگر یہ TextView، ImageView یا Button سے ان کے معیاری سائز کے ساتھ وراثت پاتا ہے، تو onMeasure کو تبدیل کیے بغیر چھوڑا جا سکتا ہے۔ ViewGroup کے لیے، onMeasure کو اوور رائڈ کرنا ہمیشہ ضروری ہے — ورنہ بچے صحیح طریقے سے نہیں ناپے جائیں گے۔

اگر setMeasuredDimension کال نہ کیا جائے تو کیا ہوتا ہے؟

Android سسٹم IllegalStateException پھینکتا ہے جس میں پیغام “The View did not call setMeasuredDimension” ہوتا ہے۔ یہ استثنا measure() طریقہ میں onMeasure مکمل ہونے کے بعد ہوتا ہے، اگر حتمی طول و عرض صفر رہ گئے ہوں۔ try-catch کے ذریعے نہ سنبھالے جانے پر استثنا ایپلیکیشن کو کریش کر دیتا ہے۔

getWidth اور getMeasuredWidth میں کیا فرق ہے؟

getMeasuredWidth() onMeasure (پیمائش کے مرحلے) میں مقرر کردہ سائز واپس کرتا ہے۔ getWidth() اصل سائز واپس کرتا ہے جو View کو onLayout میں تمام مقام کی ایڈجسٹمنٹ کے بعد ملا۔ زیادہ تر View کے لیے یہ قدریں ملتی ہیں، لیکن کسٹم ViewGroup میں یہ مختلف ہو سکتی ہیں۔

کیا onMeasure کے اندر اینیمیشن یا View حالت تبدیل کی جا سکتی ہے؟

نہیں، onMeasure صرف سائز کے حساب کے لیے ہے۔ اس طریقہ میں حالت تبدیل کرنا، اینیمیشن شروع کرنا، نیٹ ورکنگ کرنا یا ڈیٹا اپ ڈیٹ کرنا Android فن تعمیر کی خلاف ورزی کرتا ہے اور بار بار measure کالز کا سبب بن سکتا ہے، کیونکہ حالت میں تبدیلیاں requestLayout کو متحرک کر سکتی ہیں۔

onMeasure ConstraintLayout کے ساتھ کیسے تعامل کرتا ہے؟

ConstraintLayout متعین رکاوٹوں کی بنیاد پر بچوں کی پیمائش کو آزادانہ طور پر منظم کرتا ہے۔ اگر ConstraintLayout کے اندر کوئی کسٹم View onMeasure کو اوور رائڈ کرتا ہے، تو اسے ConstraintLayout سے بھیجے گئے MeasureSpec کو صحیح طریقے سے سنبھالنا چاہیے، ورنہ رکاوٹیں کام نہیں کر سکتیں۔ ConstraintLayout حساب کے لیے اپنے WidgetContainer کے ساتھ دو پاس الگورتھم استعمال کرتا ہے۔

خلاصہ

  • onMeasure() — طول و عرض کا تعین کرنے والا View طریقہ، پیمائش کے مرحلے میں Android سسٹم کے ذریعے کال کیا جاتا ہے
  • MeasureSpec پیمائش کے موڈ (EXACTLY, AT_MOST, UNSPECIFIED) اور پیرنٹ سے بھیجے گئے سائز کو انکوڈ کرتا ہے
  • setMeasuredDimension — onMeasure کے آخر میں لازمی کال جو حتمی طول و عرض مقرر کرتی ہے
  • resolveSize — ایک معاون طریقہ جو معیاری MeasureSpec ہینڈلنگ منطق کو ایک لائن میں نافذ کرتا ہے
  • دو پاس الگورتھم پیرنٹ-بچے کے درجہ بندی میں درست پیمائش کو یقینی بناتا ہے
  • measureChildWithMargins کسٹم ViewGroup میں مارجن کے ساتھ چائلڈ View ناپنے کے لیے استعمال ہوتا ہے
  • GC اور فریم ڈراپ کے خطرے کی وجہ سے onMeasure کے اندر آبجیکٹ بنانا سختی سے منع کیا جاتا ہے

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

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

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

مزید پڑھیں