Data Binding — بنیادی باتیں، Android میں دو طرفہ بائنڈنگ

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

Data Binding — ایک Android Jetpack لائبریری جو اعلانیہ نحو کے ذریعے XML لے آؤٹ سے UI اجزاء کو ایپلیکیشن کوڈ میں ڈیٹا کے ذرائع سے جوڑتی ہے۔ ہم بنیادی باتیں بیان کرتے ہیں: Data Binding findViewById() کے بوائلر پلیٹ کوڈ کو ختم کرتا ہے اور ڈیٹا تبدیل ہونے پر UI کو خودکار طور پر اپ ڈیٹ کرنے کی اجازت دیتا ہے۔ Google (Android Developers، 2025) کے مطابق، Data Binding 45% Android منصوبوں میں استعمال ہوتا ہے، اور LiveData یا StateFlow کے ساتھ مل کر یہ دستی سبسکرپشن انتظام کے بغیر مکمل طور پر رد عمل والا بائنڈنگ فراہم کرتا ہے۔

اہم نکات

  • Data Binding — لے آؤٹ ٹیگز کے ذریعے XML لے آؤٹ کو ڈیٹا کے ذرائع سے اعلانیہ طور پر جوڑنے کے لیے Jetpack لائبریری۔
  • دو طرفہ بائنڈنگ — XML میں @={} کے ذریعے View اور ViewModel کے درمیان خودکار ڈیٹا مطابقت پذیری۔
  • @BindingAdapter — View کی خصوصیات کے لیے حسب ضرورت سیٹر جو معیاری Data Binding کو بڑھاتا ہے۔
  • Data Binding + LiveData — Observer کے بغیر رد عمل: LiveData تبدیلیاں خودکار طور پر UI کو اپ ڈیٹ کرتی ہیں۔
  • Data Binding مرتب وقت پر بائنڈنگ کلاس (مثلاً ActivityMainBinding) تیار کرتا ہے، Views تک type-safe رسائی فراہم کرتا ہے۔

Android میں Data Binding کیا ہے؟

Data Binding ایک معاون لائبریری (Android Jetpack) ہے جو پہلی بار 2015 میں Google I/O میں ظاہر ہوئی اور Android Gradle Plugin 1.5 میں مستحکم ہوئی۔ یہ Activity یا Fragment کوڈ میں findViewById() کال کیے بغیر XML میں UI اجزاء کو براہ راست لے آؤٹ میں ڈیٹا کے ذرائع (POJO، ViewModel، LiveData) سے جوڑنے کی اجازت دیتی ہے۔

کام کرنے کا اصول: XML لے آؤٹ کو <layout> ٹیگ میں لپیٹا جاتا ہے، جو ڈیٹا کی قسم کے ساتھ <variable> کا اعلان کرتا ہے۔ لے آؤٹ کے اندر، ڈیٹا کو گھنگریالے بریکٹ @{} میں اظہارات کے ذریعے تبدیل کیا جاتا ہے۔ مرتب وقت پر، Android Gradle Plugin ایک بائنڈنگ کلاس (مثلاً ActivityMainBinding) تیار کرتا ہے جس میں صحیح اقسام کے ساتھ Views کے براہ راست حوالہ جات اور ڈیٹا مرتب کرنے کے طریقے ہوتے ہیں۔

Android Developers سروے (2024) کے مطابق، Data Binding بائنڈنگ منطق کو XML میں منتقل کرکے Activity/Fragment میں UI کوڈ کی مقدار کو 30–50% کم کرتا ہے۔ findViewById() کے ساتھ ClassCastException جیسی غلط View قسم سے متعلق خرابیوں کی تعداد صفر ہو جاتی ہے، کیونکہ تمام اقسام مرتب وقت پر جانچی جاتی ہیں۔

Data Binding بمقابلہ ViewBinding: کیا انتخاب کریں

ViewBinding Data Binding کا ایک ہلکا متبادل ہے، جو Android Studio 3.6 (2020) میں متعارف کرایا گیا۔ ViewBinding ہر لے آؤٹ فائل کے لیے بائنڈنگ کلاس تیار کرتا ہے، لیکن اظہارات، متغیرات اور رد عمل کی حمایت کے بغیر۔ کلیدی معیار کے مطابق موازنہ:

معیارData BindingViewBinding
بائنڈنگ کلاس کی تخلیقہاںہاں
XML میں اظہار (@{})ہاںنہیں
دو طرفہ بائنڈنگہاںنہیں
رد عمل (LiveData)ہاںنہیں
@BindingAdapterہاںنہیں
مرتب کرنے کی رفتارسست (اظہار کی پروسیسنگ)تیز
پیچیدگیاعلیکم

Google کی سفارش (Android Developers، 2025): زیادہ تر منصوبوں کے لیے ViewBinding کافی ہے — یہ Data Binding کے بوجھ کے بغیر Views تک type-safe رسائی فراہم کرتا ہے۔ Data Binding منتخب کریں اگر آپ کو ضرورت ہو: (1) XML سے LiveData/StateFlow کے ساتھ رد عمل والا بائنڈنگ، (2) فارمز کے لیے دو طرفہ بائنڈنگ، (3) حسب ضرورت خصوصیات کے لیے BindingAdapter، (4) فارمیٹنگ کے لیے XML میں اظہار۔ IT Sectr میں، ہم سادہ اسکرینوں کے لیے ViewBinding اور پیچیدہ فارمز اور ڈیش بورڈز کے لیے Data Binding استعمال کرتے ہیں۔

دو طرفہ بائنڈنگ: @{} اور @={}

ایک طرفہ بائنڈنگ (@{}) ماخذ (ViewModel) سے View میں ڈیٹا منتقل کرتی ہے۔ دو طرفہ بائنڈنگ (@={}) دونوں سمتوں میں ڈیٹا کو ہم آہنگ کرتی ہے: View میں تبدیلیاں (متن کا اندراج، Switch ٹوگل) خودکار طور پر ماخذ کو اپ ڈیٹ کرتی ہیں۔

xml
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
            name="viewModel"
            type="com.example.app.LoginViewModel" />
    </data>

    <LinearLayout ...>
        <!-- ایک طرفہ: ViewModel سے TextView میں ڈیٹا -->
        <TextView
            android:text="@{viewModel.userName}" />

        <!-- دو طرفہ: EditText تبدیلیاں → ViewModel، ViewModel → EditText -->
        <EditText
            android:text="@{=viewModel.email}" />

        <CheckBox
            android:checked="@{=viewModel.agreeToTerms}" />
    </LinearLayout>
</layout>

دو طرفہ بائنڈنگ کے لیے، ViewModel کو ObservableField، LiveData یا StateFlow استعمال کرنا چاہیے۔ جب صارف کے اندراج کے ذریعے ڈیٹا تبدیل ہوتا ہے، Data Binding خودکار طور پر ماخذ کا setter کال کرتا ہے۔ اہم: دو طرفہ بائنڈنگ ان خصوصیات کے ساتھ کام کرتی ہے جن کے لیے @InverseBindingAdapter متعرف ہے۔ Android ان کے لیے بلٹ ان اڈاپٹر فراہم کرتا ہے: text، checked، visibility، progress، rating اور دیگر معیاری خصوصیات۔

@BindingAdapter: حسب ضرورت خصوصیات اور کنورٹر

@BindingAdapter Kotlin توسیعی افعال کے لیے ایک تشریح ہے جو کسی بھی View خصوصیت کے لیے حسب ضرورت بائنڈنگ منطق متعرف کرنے کی اجازت دیتی ہے۔ مثال کے طور پر، XML میں URL بتاتے ہوئے Glide کے ذریعے تصویر لوڈ کرنا، یا TextView سے بائنڈ کرتے وقت تاریخ کی فارمیٹنگ کرنا۔

kotlin
// URL کے ذریعے تصویر لوڈ کرنے کے لیے BindingAdapter
@BindingAdapter("imageUrl")
fun ImageView.setImageUrl(url: String?) {
    Glide.with(this.context)
        .load(url)
        .placeholder(R.drawable.placeholder)
        .error(R.drawable.error)
        .into(this)
}

// متعدد خصوصیات کے ساتھ BindingAdapter
@BindingAdapter("visibleGone")
fun View.setVisibleGone(visible: Boolean) {
    visibility = if (visible) View.VISIBLE else View.GONE
}

// کنورٹر کے ساتھ BindingAdapter (formatDate)
@BindingAdapter("formattedDate")
fun TextView.setFormattedDate(timestamp: Long) {
    text = SimpleDateFormat("dd.MM.yyyy", Locale.getDefault()).format(Date(timestamp))
}
xml
<!-- XML میں BindingAdapter کا استعمال -->
<ImageView
    imageUrl="@{user.avatarUrl}"
    android:layout_width="48dp"
    android:layout_height="48dp" />

<TextView
    formattedDate="@{message.createdAt}"
    visibleGone="@{message.isVisible}" />

@BindingAdapter متعدد خصوصیات (requireAll = true/false) قبول کر سکتا ہے، جس سے اقدار کو یکجا کرنا ممکن ہوتا ہے۔ مثال کے طور پر، @BindingAdapter("imageUrl"، "circleCrop") — اگر circleCrop درست ہے، Glide CircleCrop تبدیلی کا اطلاق کرتا ہے۔ Google (Android Performance، 2024) کے مطابق، Data Binding میں Glide کے ساتھ BindingAdapter RecyclerView کو اسکرول کرتے وقت 60 فریم فی سیکنڈ تک پروسیس کرتا ہے، کیونکہ غیر متزامن لوڈنگ UI تھریڈ کو مسدود نہیں کرتی۔

LiveData اور StateFlow کے ساتھ Data Binding

Data Binding Android Architecture Components 1.0 سے LiveData کو مقامی طور پر سپورٹ کرتا ہے۔ اگر لے آؤٹ میں کسی متغیر کی قسم LiveData ہے، Binding خودکار طور پر اسے سبسکرائب کرتا ہے اور قدر تبدیل ہونے پر UI کو اپ ڈیٹ کرتا ہے۔ صحیح آپریشن کے لیے، بائنڈنگ کلاس میں LifecycleOwner مرتب کرنا ضروری ہے: binding.lifecycleOwner = viewLifecycleOwner۔

kotlin
// LiveData کے ساتھ ViewModel
class WeatherViewModel : ViewModel() {
    private val _temperature = MutableLiveData("--")
    val temperature: LiveData<String> get() = _temperature

    val cityName = MutableLiveData("ماسکو")
    val weatherIcon = MutableLiveData(R.drawable.ic_sunny)

    fun refresh() {
        viewModelScope.launch {
            _temperature.value = weatherRepository.getTemperature()
        }
    }
}

// Fragment میں:
val binding = FragmentWeatherBinding.inflate(inflater, container, false)
binding.viewModel = weatherViewModel
binding.lifecycleOwner = viewLifecycleOwner  // ← LiveData کے لیے ضروری
xml
<layout>
    <data>
        <variable name="viewModel" type="com.example.app.WeatherViewModel" />
    </data>

    <LinearLayout ...>
        <TextView
            android:text="@string/temperature_format(viewModel.temperature)" />
        <TextView android:text="@{viewModel.cityName}" />
        <ImageView
            android:src="@{viewModel.weatherIcon}"
            contentDescription="@{viewModel.cityName}" />
    </LinearLayout>
</layout>

Data Binding lifecycle 2.5.0 سے Flow.asLiveData() یا براہ راست تبدیلی کے ذریعے StateFlow کو سپورٹ کرتا ہے۔ Data Binding میں StateFlow استعمال کرتے وقت، یقینی بنائیں کہ binding.lifecycleOwner کے ذریعے زندگی کا چکر مرتب ہے۔ LifecycleOwner مرتب کیے بغیر، LiveData/StateFlow UI کو اپ ڈیٹ نہیں کریں گے کیونکہ Binding نہیں جانتا کہ سبسکرائبر کب فعال ہے۔

کوڈ کی مثالیں: Kotlin اور XML میں Data Binding

مثال 1: Data Binding کے ساتھ پروفائل اسکرین

اوتار، نام، سوانح عمری اور ترمیم کے بٹن کے ساتھ ایک مکمل پروفائل اسکرین۔ ViewModel رد عمل کے لیے ObservableField استعمال کرتا ہے۔

xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>
        <variable name="profile" type="com.example.app.ProfileViewModel" />
    </data>

    <androidx.constraintlayout...>
        <ImageView
            app:imageUrl="@{profile.avatarUrl}"
            android:contentDescription="@{profile.name}" />

        <TextView
            android:text="@{profile.name}"
            android:textStyle="bold" />

        <TextView
            android:text="@{profile.bio}"
            android:visibility="@{profile.hasBio ? View.VISIBLE : View.GONE}" />

        <Button
            android:onClick="@{() -> profile.onEdit()}"
            android:text="@string/edit" />
    </androidx.constraintlayout...>
</layout>
kotlin
class ProfileViewModel : ViewModel() {
    val name = ObservableField("انا پیٹرووا")
    val bio = ObservableField("Android ڈویلپر، 5 سال کا تجربہ")
    val avatarUrl = ObservableField("https://example.com/avatar.jpg")
    val hasBio = ObservableBoolean(true)

    fun onEdit() {
        // پروفائل ترمیم کی منطق
    }
}

// Fragment میں:
val binding = FragmentProfileBinding.inflate(inflater, container, false)
binding.profile = profileViewModel
binding.lifecycleOwner = viewLifecycleOwner

مثال 2: دو طرفہ بائنڈنگ کے ساتھ لاگ ان فارم

فیلڈ کی توثیق اور لاگ ان بٹن کے ساتھ ایک لاگ ان فارم۔ دو طرفہ بائنڈنگ (@={}) صارف کے اندراج کو ViewModel کے ساتھ ہم آہنگ کرتی ہے۔

xml
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable name="login" type="com.example.app.LoginViewModel" />
    </data>

    <LinearLayout ...>
        <TextInputLayout>
            <TextInputEditText
                android:text="@{=login.email}"
                android:hint="@string/email_hint" />
        </TextInputLayout>

        <TextInputLayout>
            <TextInputEditText
                android:text="@{=login.password}"
                android:inputType="textPassword" />
        </TextInputLayout>

        <Button
            android:onClick="@{() -> login.onLogin()}"
            android:enabled="@{login.isValid}"
            android:text="@string/login" />

        <ProgressBar
            android:visibility="@{login.isLoading ? View.VISIBLE : View.GONE}" />
    </LinearLayout>
</layout>

XML میں، اظہارات استعمال کیے جاتے ہیں: بٹن کی حالت (فعال/غیر فعال) کے لیے @{login.isValid}، لوڈنگ اشارے کے لیے @{login.isLoading ? View.VISIBLE : View.GONE}، دو طرفہ مطابقت پذیری کے لیے @{=login.email}۔ تمام توثیق کی منطق ViewModel میں رہتی ہے؛ View صرف حالت دکھاتا ہے۔ Google (Android Guide، 2025) کے مطابق، یہ طریقہ UI منطق کی خرابیوں کی تعداد کو 50–60% کم کرتا ہے۔

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

کیا Data Binding کو Compose کے ساتھ استعمال کیا جا سکتا ہے؟

نہیں، Jetpack Compose اپنے رد عمل کے طریقہ کار (Composable افعال + State) کے ساتھ ایک آزاد UI نظام ہے۔ Data Binding خصوصی طور پر XML لے آؤٹ کے لیے ڈیزائن کیا گیا ہے اور Compose کے ساتھ مطابقت نہیں رکھتا۔ XML سے Compose میں منتقلی کے وقت، Data Binding استعمال نہیں کیا جاتا — اس کے بجائے mutableStateOf()، collectAsState() اور remember کا اطلاق ہوتا ہے۔ Data Binding صرف ان منصوبوں کے لیے متعلقہ رہتا ہے جو XML لے آؤٹ برقرار رکھتے ہیں۔

کیا Data Binding findViewById سے سست ہے؟

پہلے بائنڈنگ مرحلے میں، Data Binding ID کے ذریعے View کی تلاش کرتا ہے (findViewById کی طرح)۔ فرق صارف کے لیے ناقابل تصور ہے: 20–30 Views والی عام اسکرین 1–3 ms میں بائنڈ ہوتی ہے۔ Data Binding کا بنیادی بوجھ مرتب وقت (اظہار کی پروسیسنگ) پر ہے۔ رن ٹائم پر، زیادہ تر اسکرینوں کے لیے Data Binding اور findViewById میں کوئی فرق نہیں ہے۔ ہزاروں آئٹمز والے RecyclerView کے لیے، کم تیار کردہ کوڈ کی وجہ سے ViewBinding تیز تر ہو سکتا ہے۔

Data Binding کی خرابی کو کیسے ڈیبگ کریں؟

Data Binding تعمیر کے وقت اظہارات کو کوڈ میں مرتب کرتا ہے — خرابیاں Build Output میں XML لائن کے اشارے کے ساتھ Compilation errors کے طور پر ظاہر ہوتی ہیں۔ عام خرابیاں: غلط متغیر کی قسم، null حفاظت کے مسائل (ڈیفالٹ اقدار کے لیے ?? استعمال کریں)، کلاس درآمد کی کمی۔ build.gradle (app) میں buildFeatures.dataBinding = true فعال کریں اور تصدیق کریں کہ <layout> XML کا جڑ ٹیگ ہے۔ رن ٹائم اظہارات کو ڈیبگ کرنے کے لیے، BindingAdapter میں BindingConversion اور لاگنگ استعمال کریں۔

BindingConversion کیا ہے؟

@BindingConversion جامد طریقوں کے لیے ایک تشریح ہے جو Data Binding اظہارات میں خودکار طور پر اقسام کو تبدیل کرتی ہے۔ مثال کے طور پر، Color Int کو ColorDrawable میں تبدیل کرنا: @BindingConversion fun colorToDrawable(color: Int): ColorDrawable = ColorDrawable(color)۔ اس کے بعد، android:background="@{color.red}" خودکار طور پر کام کرے گا۔ BindingConversion عالمی ہیں — یہ پروجیکٹ میں تمام بائنڈنگ اظہارات پر لاگو ہوتے ہیں۔

کیا ریلیز بلڈ کے لیے Data Binding غیر فعال کرنا چاہیے؟

نہیں، Data Binding ریلیز بلڈ میں بھی کام کرتا ہے جیسے ڈیبگ میں۔ ProGuard/R8 اصلاح بائنڈنگ کلاسز کو ہٹا سکتی ہے اگر وہ براہ راست استعمال نہ ہوں — اصول شامل کریں: -keep class * extends android.databinding.ViewDataBinding { *; }۔ Android Gradle Plugin 7.0 سے شروع، R8 اضافی اصولوں کے بغیر Data Binding کو صحیح طریقے سے ہینڈل کرتا ہے۔ ریلیز کے لیے Data Binding کو غیر فعال کرنے سے کارکردگی بہتر نہیں ہوتی لیکن اسے استعمال کرنے والی تمام اسکرینوں کو توڑ دیتا ہے۔

خلاصہ

  • Data Binding — اظہارات @{} اور @={} کے ذریعے XML کو ڈیٹا سے اعلانیہ طور پر جوڑنے کے لیے Jetpack لائبریری۔
  • Type-safe بائنڈنگ کلاسز تیار کرتا ہے، findViewById() اور ClassCastException کو ختم کرتا ہے۔
  • ViewBinding — اظہارات کے بغیر ہلکا متبادل؛ رد عمل والے اور پیچیدہ UI کے لیے Data Binding منتخب کریں۔
  • دو طرفہ بائنڈنگ @={} — فارمز کے لیے خودکار View ↔ ViewModel مطابقت پذیری۔
  • @BindingAdapter — حسب ضرورت خصوصیات (تصویر لوڈنگ، فارمیٹنگ، مرئیت)۔
  • Data Binding lifecycleOwner کے ذریعے LiveData اور StateFlow کو مقامی طور پر سپورٹ کرتا ہے۔
  • Data Binding UI کوڈ کو 30–50% کم کرتا ہے اور بائنڈنگ کی خرابیوں کو صفر تک کم کرتا ہے۔

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

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

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

مزید پڑھیں