کاسٹم ویو — اینڈرائیڈ میں جوہر، ڈرائینگ اور ایونٹ ہینڈلنگ

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

Custom View — یہ اینڈرائڈ میں ایک حسب ضرورت انٹرفیس کمپوننٹ ہے، جو View کلاس یا اس کے ذیلی کلاسز (Button, TextView, ImageView) سے وراثت حاصل کرکے اور کلیڈی میتھڈز کو اوور رائڈ کرکے بنایا جاتا ہے: onDraw ڈرائینگ کے لیے، onMeasure سائز کی پیمائش کے لیے اور onTouchEvent ٹچ ہینڈلنگ کے لیے۔ Google Android Developer Guide (2024) کے مطابق، Custom View اس وقت استعمال ہوتا ہے جب Android SDK کے معیاری کمپوننٹ مطلوبہ رویہ یا ظاہری شکل فراہم نہیں کرتے — مثال کے طور پر، کسٹم اینیمیشن، غیر معیاری اشکال، مخصوصی گراف اور گیم عناصر کے لیے۔

اہم نکات

  • Custom View — View یا اس کے ذیلی کلاسز سے وراثت حاصل کرکے onDraw, onMeasure, onTouchEvent کو اوور رائڈ کرتے ہوئے بنایا جاتا ہے۔
  • ڈرائینگ Canvas API کے ذریعے کی جاتی ہے — ہندسی اشکال، متن، راستے، Bitmap اور اینیمیشن۔
  • onMeasure layout-پیرامیٹرز اور padding کو مدنظر رکھتے ہوئے View کے درست سائز کے لیے ذمہ دار ہے۔
  • حسب ضرورت XML-خصوصیات res/values/attrs.xml میں اعلان کی جاتی ہیں اور View کے کنسٹرکٹر میں پڑھی جاتی ہیں۔
  • ٹچ ہینڈلنگ onTouchEvent اشاروں، drag-and-drop اور ملٹی ٹچ کی سپورٹ شامل کرنے کی اجازت دیتا ہے۔

اینڈرائڈ میں Custom View کیا ہے؟

Custom View — ایک کلاس ہے جو android.view.View (یا اس کے کسی ایک ذیلی کلاس) سے وراثت حاصل کرتا ہے، جو اپنی ڈرائینگ، پیمائش اور یونٹ ہینڈلنگ کی منطق کو نفذ کرنے کے لیے سیسٹم میتھڈز کو اوور رائڈ کرتا ہے۔ Custom View منفرد UI کمپوننٹ بنانے کا ایک بنیادی اینڈرائڈ میکینزم ہے۔

Android Custom View بنانے کے دو طریقے فراہم کرتا ہے: View سے وراثت (مکمل طور پر کسٹم ڈرائینگ onDraw کے ذریعے) اور موجودہ View-ذیلی کلاس سے وراثت (مثال کے طور پر، Button یا TextView کو اوور رائڈ کرکے بنیادی رویہ کو برقرار رکھتے ہوئے فنکشنالٹی شامل کرنے کے لیے)۔

بنیادی کنسٹرکٹر Custom View کو Context اور AttributeSet لینا چاہیے — یہ سیسٹم کو XML سے View بنانے کی اجازت دیتا ہے۔ اگر View صرف کوڈ سے استعمال ہوگا، تو Context کے ساتھ کنسٹرکٹر کافی ہے۔ ساتھ کا کنسٹرکٹر اسٹائل کے ساتھ Android ثیم کی سپورٹ کے لیے ضروری ہے۔

kotlin
class CustomView
    @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    private val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.BLUE
        strokeWidth = 4f
        style = Paint.Style.FILL
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        canvas.drawCircle(width / 2f,
            height / 2f,
            50f, paint)
    }
}

کم از کم Custom View کنسٹرکٹر اور onDraw پر مشتمل ہہ۔ تاہم Android کے Layout سیسٹم میں درست کام کے لیے onMeasure کو بھی اوور رائڈ کرنا ضروری ہے — ورنہ View صفر سائز کے ساتھ ظاہر ہو سکتا ہے یا wrap_content layout-پیرامیٹرز پر غلط عمل کر سکتا ہے۔

Google I/O 2023 کے مطابق، ٹاپ-100 Google Play ایپس میں سے 65% کسٹم View استعمال کرتے ہیں۔ Custom View بنانے کی سب سے عام وجوہات: غیر معیاری اینیمیشنز (35%)، کسٹم گراف اور ڈائیگرام (25%)، مخصوصی کنٹرول عناصر (20%) اور برینڈڈ کمپوننٹ (20%)۔

onMeasure اور onLayout: سائز کا انتظام

onMeasure — یہ وہ میتھڈ ہے جس میں View اپنے مطلوبہ سائز کے بارے میں منتقل کردہ MeasureSpec (والدین پابندیاں) کی بنیاد پر سیسٹم کو مطلع کرتا ہے۔ onMeasure کی درست تعمیل کے بغیر View کی اونچائی صفر ہو سکتی ہے wrap_content پر یا match_parent پر پوری سکرین گھیر سکتی ہے۔

MeasureSpec موڈ (EXACTLY, AT_MOST, UNSPECIFIED) اور مقدار پر مشتمل ہے۔ EXACTLY — والد نے عین سائز مقرر کیا (match_parent یا مقرر قیمت)۔ AT_MOST — والد نے ادھتم مقرر کیا (wrap_content)۔ UNSPECIFIED — بغیر پابندی (ScrollView, ListView)۔

kotlin
override fun onMeasure(
    widthMeasureSpec: Int,
    heightMeasureSpec: Int
) {
    val desiredWidth = paddingLeft + paddingRight
        + DEFAULT_WIDTH
    val desiredHeight = paddingTop + paddingBottom
        + DEFAULT_HEIGHT

    val measuredWidth = MeasureSpec.getSize(widthMeasureSpec)
    val modeWidth = MeasureSpec.getMode(widthMeasureSpec)

    val resultWidth = when (modeWidth) {
        MeasureSpec.EXACTLY -> measuredWidth
        MeasureSpec.AT_MOST ->
            desiredWidth.coerceAtMost(measuredWidth)
        else -> desiredWidth
    }

    val resultHeight = resolveSize(desiredHeight,
        heightMeasureSpec)

    setMeasuredDimension(resultWidth, resultHeight)
}

resolveSize — یہ ایک Android یوٹیلٹی میتھڈ ہے جو onMeasure کی تعمیل کو آسان بناتا ہے۔ یہ مطلوبہ سائز اور MeasureSpec لیتا ہے اور درست قیمت واپس کرتا ہے: EXACTLY کے لیے — عین سائز، AT_MOST کے لیے — مطلوبہ اور ادھتم میں سے کم، UNSPECIFIED کے لیے — مطلوبہ سائز۔

onLayout View (نہ کہ ViewGroup) کے لیے عموماً اوور رائڈ نہیں کیا جاتا — یہ والد کے ذریعے بچوں کو پزیشن دینے کے لیے بلایا جاتا ہے۔ ViewGroup کے لیے onLayout لازمی ہے — اس میں ہر ذیلی View کے لیے layout() کو کال کرنا ضروری ہے۔

onDraw اور Canvas API: ڈرائینگ

onDraw — Custom View کا دل ہے۔ یہ میتھڈ Android کے ذریعے ہر دفعہ View کی دوبارہ ڈرائینگ پر بلایا جاتا ہے۔ اس میں Canvas آبجیکٹ دیا جاتا ہے، جس کے ذریعے ساری ڈرائینگ کی جاتی ہے: ہندسی اشکال، متن، راستے، Bitmap اور اینیمیشنز۔

Canvas API تمام بنیادی کاروائیں کے لیے میتھڈ فراہم کرتا ہے: drawCircle, drawRect, drawLine, drawPath, drawText, drawBitmap, drawArc, drawOval۔ اسٹائل کو کنفیگر کرنے کے لیے Paint استعمال ہوتا ہے — ایک آبجیکٹ جو رنگ، موٹائی، بھرنے کا اسٹائل، فونٹ، سایہ اور افیکٹس متعین کرتا ہے۔

kotlin
override fun onDraw(canvas: Canvas) {
    super.onDraw(canvas)

    // پس منظر
    canvas.drawRect(0f, 0f,
        width.toFloat(), height.toFloat(), bgPaint)

    // متن
    canvas.drawText("کاسٹم ویو",
        paddingLeft.toFloat(),
        paddingTop.toFloat() + textPaint.textSize,
        textPaint)

    // دائرہ
    canvas.drawCircle(
        width / 2f,
        height / 2f,
        radius, circlePaint)

    // پاتھ (بیزیئر کریو)
    val path = Path().apply {
        moveTo(0f, height.toFloat())
        quadTo(width / 2f, 0f,
            width.toFloat(), height.toFloat())
    }
    canvas.drawPath(path, pathPaint)
}

Paint — یہ ڈرائینگ اسٹائل کا کنفیگریٹر ہے۔ انٹی ایلیئسنگ (Paint.ANTI_ALIAS_FLAG) ہموار کناروں کے لیے لازمی ہے۔ Subpixel text (SUBPIXEL_TEXT_FLAG) متن کے معیار کو بہتر بناتا ہے۔ Style.FILL, STROKE اور FILL_AND_STROKE متعین کرتے ہیں کہ شکل بھری جائے گی، صرف کنارے سے بنے یا دونوں۔

اہم: onDraw میں Paint, Path, Rect آبجیکٹز نہ بنائیں — یہ ڈرائینگ لوپ میں ایلوکیشنز کا سبب بنتا ہے اور گاربیج کلکشن کو متحرک کرتا ہے، جس سے FPS گر جاتا ہے۔ تمام ڈرائینگ آبجیکٹز کو کنسٹرکٹر یا init میتھڈ میں بنائیں۔ اینیمیشن کے لیے ValueAnimator یا ObjectAnimator کو invalidate() کے ساتھ استعمال کریں تاکہ دوبارہ ڈرائینگ شروع ہو۔

attrs.xml میں حسب ضرورت XML-خصوصیات

حسب ضرورت خصوصیات آپکو XML سے Custom View کو اسی طرح کنفیگر کرنے کی اجازت دیتی ہیں جیسے معیاری android:layout_width یا android:background۔ یہ خصوصیات res/values/attrs.xml فائل میں نام، قسم اور اختیاری ڈفالٹ مقدار کے ساتھ اعلان کی جاتی ہیں۔

خصوصیات کی قسمیں: string, integer, float, boolean, color, dimension, enum, flag, fraction, reference (وسائل کا حوالہ)۔ ہر قسم کے لیے Android خودکار XML سے مقدار پارس کرتا ہے اور TypedArray میں منتقل کرتا ہے۔

xml
<!-- res/values/attrs.xml -->
<resources>
    <declare-styleable name="CustomView">
        <attr name="circleColor"
            format="color" />
        <attr name="circleRadius"
            format="dimension" />
        <attr name="labelText"
            format="string" />
        <attr name="showAnimation"
            format="بولین" />
    </declare-styleable>
</resources>

Custom View کے کنسٹرکٹر میں خصوصیات context.obtainStyledAttributes کے ذریعے پڑھی جاتی ہیں، جو TypedArray واپس کرتا ہے۔ TypedArray ٹائپ کے مطابق رسائی کے میتھڈ فراہم کرتا ہے: getColor, getDimension, getString, getBoolean, getInt۔ پڑھنے کے بعد وسائل آزاد کرنے کے لیے TypedArray پر recycle() کال کرنا لازمی ہے۔

kotlin
init {
    val typedArray = context.obtainStyledAttributes(
        attrs,
        R.styleable.CustomView
    )

    circleColor = typedArray.getColor(
        R.styleable.CustomView_circleColor,
        Color.BLUE
    )
    circleRadius = typedArray.getDimension(
        R.styleable.CustomView_circleRadius,
        50f
    )
    labelText = typedArray.getString(
        R.styleable.CustomView_labelText
    ) ?: "Default"

    typedArray.recycle()
}

XML میں استعمال: نیم سپیس app (شامل کریں xmlns:app="http://schemas.android.com/apk/res-auto") اور حسب ضرورت خصوصیات کو app:circleColor="@color/red" کے طور پر استعمال کریں۔ اگر attrs.xml میں اعلان درست ہے تو Android Studio autocomplete کرے گا اور خصوصیات کی قسموں کی تصدیق کرے گا۔

onTouchEvent کے ساتھ ٹچ ہینڈلنگ

onTouchEvent — وہ میتھڈ ہے جو View کے ہر ٹچ پر بلایا جاتا ہے۔ یہ MotionEvent آبجیکٹ وصول کرتا ہے جس میں ایونٹ کی قسم (ACTION_DOWN, ACTION_MOVE, ACTION_UP, ACTION_CANCEL)، مقامات، دباؤ اور انگلیوں کی تعداد (ملٹی ٹچ) کے بارے میں معلومات ہوتی ہے۔

پځیدگی اشاروں (سوائپ، زوم، لمبے دباؤ) کی پروسیسنگ کے لیے GestureDetector یا ScaleGestureDetector کو onTouchEvent کے ساتھ استعمال کریں۔ GestureDetector onSingleTapUp, onFling, onLongPress, onDoubleTap اور دیگر معیاری اشاروں کی پہچان کو آسان بناتا ہے۔

kotlin
private val gestureDetector = GestureDetector(
    context, object : GestureDetector.SimpleOnGestureListener() {
    override fun onSingleTapUp(e: MotionEvent): Boolean {
        handleTap(e.x, e.y)
        return true
    }
})

override fun onTouchEvent(event: MotionEvent): Boolean {
    val handled = gestureDetector.onTouchEvent(event)

    when (event.action) {
        MotionEvent.ACTION_MOVE -> {
            currentX = event.x
            currentY = event.y
            invalidate()
            return true
        }
    }

    return handled || super.onTouchEvent(event)
}

ہٹ ٹیسٹنگ — یہ طے کرنا کہ ٹچ View کے کس مخصوص علاقے میں ہوئی ہے۔ مستطیل علاقوں کے لیے Rect.contains(x, y) استعمال کریں۔ دائروں کے لیے — مرکز سے فاصلہ چیک کریں: sqrt(dx^2 + dy^2) < radius۔ من صلہ شکلوں کے لیے Path.op() یا Region.contains() استعمال کریں۔

ملٹی ٹچ MotionEvent.getPointerCount() اور getPointerId(index) کے ذریعے هینڈل کیا جاتا ہے۔ ہر انگلیتہ کو ایک منفرد ID ملتا ہے جو ACTION_DOWN سے ACTION_POINTER_UP تک برقرار رہتا ہے۔ ACTION_MOVE میں تمام فعال انگلیوں کا ڈیٹا ہو سکتا ہے — حرکت کی انٹرپولیشن کے لیے getHistoricalX/Y استعمال کریں۔

Custom View کی کارکردگی کی اصلاح

Custom View کارکردگی کی رکاوڙ بن سکتا ہے اگر onDraw اکثر بلایا جاتا ہے (اینیمیشن، اسکرول) یا بھاری کاروائیں شامل ہیں۔ Android کسٹم کمپوننٹز کی ڈرائینگ کی اصلاح کے لیے کائی میکینزم فراہم کرتا ہے۔

پیچیڈگی ڈرائینگ کے لیے Layer type

View.setLayerType View کی رنڈرنگ کو سافٹ ویئر (LAYER_TYPE_SOFTWARE) یا ہارڈ ویئر (LAYER_TYPE_HARDWARE) لیر میں بدلنے کی اجازت دیتا ہے۔ Software layer مشکل Canvas گرافکس کے لیے مفید ہے جو ہارڈ ویئر ایکسیلریشن میں سپورٹ نہیں ہوتیں — مثال کے طور پر، drawTextOnPath یا مشکل Path افیکٹس۔

صرف ضروری علاقے کی invalidate

invalidate(Rect) — صرف View کے مخصوص علاقے کو دوبارہ تیار کرتا ہے، پورے کمپوننٹ کو نہیں۔ یہ بڑے Custom View ( گراف، نقشے، ڈرائینگ کینواس) کے لیے نھایتی اہم ہے، جہاں ہر فریم کی مکمل دوبارہ تیاری FPS گرا دیتی ہے۔ vsync کے ساتھ مناسقت کے لیے postInvalidateOnAnimation() استعمال کریں۔

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

    // کنسٹرکٹر میں ایک بار بنائی گئی اشیاء
    private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
    private val rect = Rect()
    private val position = PointF()

    fun updatePosition(x: Float, y: Float) {
        position.set(x, y)
        // صرف پوائنٹ کے ارد گرد کے علاقے کو دوبارہ ڈرا کریں
        rect.set(
            (x - 10).toInt(),
            (y - 10).toInt(),
            (x + 10).toInt(),
            (y + 10).toInt()
        )
        invalidate(rect)
    }
}

ہارڈ ویئر ایکسیلریشن Android 3.0+ (API 11+) پر ڈفالٹ سے فعال ہے۔ drawCircle, drawRect, drawBitmap Canvas آپریشنز ہارڈ ویئر ایکسیلریت ہوتی ہیں اور GPU پر نفذ ہوتی ہیں۔ تاہم drawTextOnPath, drawVertices, پیچیڈگی clipping آپریشنز ایکسیلریت نہیں ہوتیں — ان کے لیے LAYER_TYPE_SOFTWARE استعمال کریں۔

Android Performance Patterns (Google, 2023) کے مطابق، Custom View کے لیگ کی اہم وجوہات: onDraw میں ایلوکیشنز (ہر فریم آبجیکٹ بنانا)، ایک عنصر کی تبدیلی پر پورے View کی دوبارہ تیاری اور مقدار کے مواد کے لیے LayerType.HARDWARE کی غیر موجودگی۔ ان تین مسائل کو درست کرنا زیادہ تر مناظر میں FPS کو 30 سے 60 تک بڑھاتا ہے۔

میتھڈمقصدکال کی تعداد
onDrawView کے مواد کی ڈرائینگہر invalidate() پر
onMeasureView کے سائز کا تعینlayout کی تبدیلی پر
onLayoutذیلی View کی پزیشنonMeasure کے بعد
onTouchEventٹچ کی پروسیسنگہر ٹچ پر
onSizeChangedسائز کی تبدیلی پر ری اکشنپہلے layout اور تبدیلی پر

اکثر پوچے جانے والے سوالات

Custom View کب استعمال کریں اور Compose کب؟

Custom View (Canvas API) اس وقت مناسب ہے جب کسٹم ڈرائینگ میں زیادہ سے زیادہ کارکردگی درکار ہو (گرافکس، ویڈیو ایڈیٹرز، نقشے)، موجودہ View-بنیاد کوڈ کے ساتھ انضمام یا Android API 21 سے نیچے کے ورژنز کی سپورٹ چاہی۔ Jetpack Compose زیادہ تر نئے مناصر کے لیے جدید طریقہ ہے، جو اعلانی UI استعمال کرتا ہے اور متحرک انٹرفیسز کے لیے بہتر موزوں ہے۔

کیا onMeasure کو اوور رائڈ کرنا لازمی ہے؟

ہاں، اگر View XML میں wrap_content استعمال کرتا ہے۔ onMeasure کے بغیر wrap_content match_parent کی طرح کام کرے گا، کیونکہ View.onMeasure کی معیاری تعمیل ڈفالٹ سائز مقرر نہیں کرتی۔ اگر View کا ہمیشہ مقرر سائز یا match_parent ہو، تو onMeasure کو اوور رائڈ کرنا ضروری نہیں ہے۔

Custom View کو کیسے اینیمیٹ کریں؟

View کی خصوصیات (رنگ، ریڈیئس، پزیشن) کو بدلنے کے لیے ValueAnimator یا ObjectAnimator استعمال کریں اور دوبارہ ڈرائینگ کے لیے اینیمیشن کالبیک میں invalidate() کو کال کریں۔ ValueAnimator مرکزی ثریڈ پر کام کرتا ہے اور vsync کے ساتھ مناسق ہۈتا ہے۔ مشکل اینیمیشنز (فیزیکس، ذرات) کے لیے Choreographer.FrameCallback یا Android Animation Framework استعمال کریں۔

Custom View میں ملٹی ٹچ کو کیسے ہینڈل کریں؟

onTouchEvent میں انگلیوں کی تعداد کے لیے MotionEvent.getPointerCount() اور ہر انگلیتہ کو منفرد ID سے ٹریک کرنے کے لیے getPointerId(i) استعمال کریں۔ ACTION_POINTER_DOWN / ACTION_POINTER_UP — انگلی شامل/ہٹانے کے ایونٹس ہیں۔ زوم کے لیے ScaleGestureDetector کو onTouchEvent کے ساتھ استعمال کریں — یہ pinch-to-zoom کا پتا لگانا آسان بناتا ہے۔

کیا Jetpack Compose میں Custom View استعمال کیا جا سکتا ہے؟

ہاں، AndroidView کے ذریعے — ایک composable فنکشن جو View-بنیاد عنصر کو Compose درخت میں ضم کرتا ہے۔ AndroidView View بنانے کے لیے فیکٹری اور حالت کی مناسقت کے لیے update کالبیک لیتا ہے۔ یہ آپکو موجودہ Custom View کو مکمل دوبارہ لکھنے کے بغیر نئے Compose مناصر میں دوبارہ استعمال کرنے کی اجازت دیتا ہے۔

خلاصہ

  • Custom View — ایک حسب ضرورت Android کمپوننٹ ہے، جو View سے وراثت حاصل کرکے onDraw, onMeasure اور onTouchEvent کو کسٹم ڈرائینگ اور پروسیسنگ کے لیے اوور رائڈ کرکے بنایا جاتا ہے۔
  • onDraw اور Canvas API — ڈرائینگ کی بنیاد: ہندسی اشکال، متن، Bitmap، راستے — Paint کے ذریعے رنگ، اسٹائل اور فونٹ کی کنفیگریشن کے ساتھ۔
  • onMeasure wrap_content کے درست کام کے لیے اہم ہے؛ MeasureSpec (EXACTLY, AT_MOST, UNSPECIFIED) اور resolveSize کو سائز کے حساب کے لیے استعمال کرتا ہے۔
  • حسب ضرورت خصوصیات attrs.xml اور TypedArray کے ذریعے XML سے Custom View کو Android Studio میں autocomplete کے ساتھ کنفیگر کرنے کی اجازت دیتی ہیں۔
  • onTouchEvent GestureDetector کے ساتھ ٹچ، اشاروں اور ملٹی ٹچ کی پروسیسنگ کو یقینی بناتا ہے، اور ہٹ ٹیسٹنگ باتچیت کے علاقے کو متعین کرتا ہے۔
  • کارکردگی: آبجیکٹز کو کنسٹرکٹر میں ایک بار بنائیں، جزوی دوبارہ تیاری کے لیے invalidate(Rect) استعمال کریں اور مشکل افیکٹس کے لیے LayerType استعمال کریں۔
  • Custom View Jetpack Compose کے ساتھ AndroidView کے ذریعے مضموم ہو جاتا ہے، جو تیار کمپوننٹز کو نئے Compose مناصر میں دوبارہ استعمال کرنے کی اجازت دیتا ہے۔

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

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

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

مزید پڑھیں