दो तरफ़ा डेटा बाइंडिंग

वन-वे डेटा बाइंडिंग का इस्तेमाल करके, किसी एट्रिब्यूट पर वैल्यू सेट की जा सकती है. साथ ही, एक ऐसा लिसनर सेट किया जा सकता है जो उस एट्रिब्यूट में होने वाले बदलाव पर प्रतिक्रिया देता है:

<CheckBox
    android:id="@+id/rememberMeCheckBox"
    android:checked="@{viewmodel.rememberMe}"
    android:onCheckedChanged="@{viewmodel.rememberMeChanged}"
/>

टू-वे डेटा बाइंडिंग, इस प्रोसेस को आसान बनाती है:

<CheckBox
    android:id="@+id/rememberMeCheckBox"
    android:checked="@={viewmodel.rememberMe}"
/>

@={} नोटेशन में "=" चिह्न शामिल होता है. यह प्रॉपर्टी में डेटा में होने वाले बदलावों को कैप्चर करता है और उपयोगकर्ता के अपडेट को भी ट्रैक करता है.

बैकअप डेटा में होने वाले बदलावों के हिसाब से काम करने के लिए, अपने लेआउट वैरिएबल को Observable (आम तौर पर BaseObservable) के तौर पर लागू किया जा सकता है. साथ ही, @Bindable एनोटेशन का इस्तेमाल किया जा सकता है, जैसा कि यहां दिए गए कोड स्निपेट में दिखाया गया है:

Kotlin

class LoginViewModel : BaseObservable {
    // val data = ...

    @Bindable
    fun getRememberMe(): Boolean {
        return data.rememberMe
    }

    fun setRememberMe(value: Boolean) {
        // Avoids infinite loops.
        if (data.rememberMe != value) {
            data.rememberMe = value

            // React to the change.
            saveData()

            // Notify observers of a new value.
            notifyPropertyChanged(BR.remember_me)
        }
    }
}

Java

public class LoginViewModel extends BaseObservable {
    // private Model data = ...

    @Bindable
    public Boolean getRememberMe() {
        return data.rememberMe;
    }

    public void setRememberMe(Boolean value) {
        // Avoids infinite loops.
        if (data.rememberMe != value) {
            data.rememberMe = value;

            // React to the change.
            saveData();

            // Notify observers of a new value.
            notifyPropertyChanged(BR.remember_me);
        }
    }
}

बाइंड की जा सकने वाली प्रॉपर्टी के गेटर तरीके को getRememberMe() कहा जाता है. इसलिए, प्रॉपर्टी का सेटर तरीका, अपने-आप setRememberMe() नाम का इस्तेमाल करता है.

BaseObservable और @Bindable का इस्तेमाल करने के बारे में ज़्यादा जानने के लिए, मॉनिटर किए जा सकने वाले डेटा ऑब्जेक्ट के साथ काम करना लेख पढ़ें.

कस्टम एट्रिब्यूट का इस्तेमाल करके, टू-वे डेटा बाइंडिंग

यह प्लैटफ़ॉर्म, सबसे सामान्य टू-वे एट्रिब्यूट और चेंज लिसनर के लिए, टू-वे डेटा बाइंडिंग की सुविधा देता है. इसका इस्तेमाल अपने ऐप्लिकेशन में किया जा सकता है. अगर आपको कस्टम एट्रिब्यूट के साथ टू-वे डेटा बाइंडिंग का इस्तेमाल करना है, तो आपको @InverseBindingAdapter और @InverseBindingMethod एनोटेशन के साथ काम करना होगा.

उदाहरण के लिए, अगर आपको MyView नाम के कस्टम व्यू में "time" एट्रिब्यूट पर, दोतरफ़ा डेटा बाइंडिंग की सुविधा चालू करनी है, तो यह तरीका अपनाएं:

  1. @BindingAdapter का इस्तेमाल करके, शुरुआती वैल्यू सेट करने वाले और वैल्यू बदलने पर अपडेट करने वाले तरीके को एनोटेट करें:

    Kotlin

    @BindingAdapter("time")
    @JvmStatic fun setTime(view: MyView, newValue: Time) {
        // Important to break potential infinite loops.
        if (view.time != newValue) {
            view.time = newValue
        }
    }
    

    Java

    @BindingAdapter("time")
    public static void setTime(MyView view, Time newValue) {
        // Important to break potential infinite loops.
        if (view.time != newValue) {
            view.time = newValue;
        }
    }
    
  2. @InverseBindingAdapter का इस्तेमाल करके, व्यू से वैल्यू को पढ़ने वाले तरीके के बारे में जानकारी दें:

    Kotlin

    @InverseBindingAdapter("time")
    @JvmStatic fun getTime(view: MyView) : Time {
        return view.getTime()
    }
    

    Java

    @InverseBindingAdapter("time")
    public static Time getTime(MyView view) {
        return view.getTime();
    }
    

इस समय, डेटा बाइंडिंग को पता होता है कि डेटा बदलने पर क्या करना है. यह @BindingAdapter के साथ एनोटेट किए गए तरीके को कॉल करता है. साथ ही, व्यू एट्रिब्यूट बदलने पर क्या कॉल करना है, यह भी पता होता है. यह InverseBindingListener को कॉल करता है. हालांकि, इसे यह नहीं पता होता कि एट्रिब्यूट कब या कैसे बदलता है.

इसके लिए, आपको व्यू पर एक लिसनर सेट करना होगा. यह आपके कस्टम व्यू से जुड़ा कस्टम लिसनर हो सकता है. इसके अलावा, यह कोई सामान्य इवेंट भी हो सकता है. जैसे, फ़ोकस हटना या टेक्स्ट में बदलाव होना. प्रॉपर्टी में होने वाले बदलावों के लिए, लिसनर सेट करने वाले तरीके में @BindingAdapter एनोटेशन जोड़ें:

Kotlin

@BindingAdapter("app:timeAttrChanged")
@JvmStatic fun setListeners(
        view: MyView,
        attrChange: InverseBindingListener
) {
    // Set a listener for click, focus, touch, etc.
}

Java

@BindingAdapter("app:timeAttrChanged")
public static void setListeners(
        MyView view, final InverseBindingListener attrChange) {
    // Set a listener for click, focus, touch, etc.
}

लिसनर में पैरामीटर के तौर पर InverseBindingListener शामिल होता है. InverseBindingListener का इस्तेमाल करके, डेटा बाइंडिंग सिस्टम को यह बताया जाता है कि एट्रिब्यूट में बदलाव किया गया है. इसके बाद, सिस्टम @InverseBindingAdapter का इस्तेमाल करके, एनोटेट किए गए तरीके को कॉल करना शुरू कर सकता है.

असल में, इस लिसनर में कुछ अहम लॉजिक शामिल होते हैं. इनमें वन-वे डेटा बाइंडिंग के लिए लिसनर भी शामिल हैं. उदाहरण के लिए, टेक्स्ट एट्रिब्यूट में बदलाव के लिए अडैप्टर, TextViewBindingAdapter देखें.

ग्राहक में बदलने वाले लोगों की संख्या

अगर View ऑब्जेक्ट से जुड़े वैरिएबल को दिखाने से पहले, उसे फ़ॉर्मैट करना, अनुवाद करना या किसी तरह से बदलना ज़रूरी है, तो Converter ऑब्जेक्ट का इस्तेमाल किया जा सकता है.

उदाहरण के लिए, तारीख दिखाने वाला कोई EditText ऑब्जेक्ट लें:

<EditText
    android:id="@+id/birth_date"
    android:text="@={Converter.dateToString(viewmodel.birthDate)}"
/>

viewmodel.birthDate एट्रिब्यूट में Long टाइप की वैल्यू शामिल है. इसलिए, इसे कन्वर्टर का इस्तेमाल करके फ़ॉर्मैट करना होगा.

दो-तरफ़ा एक्सप्रेशन का इस्तेमाल किया जा रहा है. इसलिए, लाइब्रेरी को यह बताने के लिए कि उपयोगकर्ता की दी गई स्ट्रिंग को वापस बैकिंग डेटा टाइप में कैसे बदला जाए, इनवर्स कन्वर्टर की भी ज़रूरत होगी. इस मामले में, Long. इसके लिए, किसी एक कन्वर्टर में @InverseMethod एनोटेशन जोड़ें. साथ ही, इस एनोटेशन को इन्वर्स कन्वर्टर के तौर पर रेफ़र करें. इस कॉन्फ़िगरेशन का एक उदाहरण, यहां दिए गए कोड स्निपेट में दिखता है:

Kotlin

object Converter {
    @InverseMethod("stringToDate")
    @JvmStatic fun dateToString(
        view: EditText, oldValue: Long,
        value: Long
    ): String {
        // Converts long to String.
    }

    @JvmStatic fun stringToDate(
        view: EditText, oldValue: String,
        value: String
    ): Long {
        // Converts String to long.
    }
}

Java

public class Converter {
    @InverseMethod("stringToDate")
    public static String dateToString(EditText view, long oldValue,
            long value) {
        // Converts long to String.
    }

    public static long stringToDate(EditText view, String oldValue,
            String value) {
        // Converts String to long.
    }
}

टू-वे डेटा बाइंडिंग का इस्तेमाल करके इनफ़ाइनाइट लूप बनाना

टू-वे डेटा बाइंडिंग का इस्तेमाल करते समय, ध्यान रखें कि इनफ़ाइनाइट लूप न बने. जब उपयोगकर्ता किसी एट्रिब्यूट में बदलाव करता है, तो @InverseBindingAdapter का इस्तेमाल करके एनोटेट किए गए तरीके को कॉल किया जाता है. साथ ही, वैल्यू को बैकिंग प्रॉपर्टी को असाइन किया जाता है. इससे, @BindingAdapter का इस्तेमाल करके एनोटेट किए गए तरीके को कॉल किया जाएगा. इससे, @InverseBindingAdapter का इस्तेमाल करके एनोटेट किए गए तरीके को एक और कॉल ट्रिगर होगा. यह लूप जारी रहेगा.

इस वजह से, @BindingAdapter का इस्तेमाल करके एनोटेट किए गए तरीकों में नई और पुरानी वैल्यू की तुलना करके, संभावित इनफ़ाइनाइट लूप को रोकना ज़रूरी है.

टू-वे एट्रिब्यूट

नीचे दी गई टेबल में मौजूद एट्रिब्यूट का इस्तेमाल करने पर, प्लैटफ़ॉर्म में टू-वे डेटा बाइंडिंग की सुविधा पहले से मौजूद होती है. यह प्लैटफ़ॉर्म, इस सुविधा को कैसे उपलब्ध कराता है, इस बारे में जानकारी पाने के लिए, इससे जुड़े बाइंडिंग अडैप्टर के लागू होने का तरीका देखें:

कक्षा एट्रिब्यूट बाइंडिंग अडैप्टर
AdapterView android:selectedItemPosition
android:selection
AdapterViewBindingAdapter
CalendarView android:date CalendarViewBindingAdapter
CompoundButton android:checked CompoundButtonBindingAdapter
DatePicker android:year
android:month
android:day
DatePickerBindingAdapter
NumberPicker android:value NumberPickerBindingAdapter
RadioButton android:checkedButton RadioGroupBindingAdapter
RatingBar android:rating RatingBarBindingAdapter
SeekBar android:progress SeekBarBindingAdapter
TabHost android:currentTab TabHostBindingAdapter
TextView android:text TextViewBindingAdapter
TimePicker android:hour
android:minute
TimePickerBindingAdapter

अन्य संसाधन

डेटा बाइंडिंग के बारे में ज़्यादा जानने के लिए, यहां दिए गए अन्य संसाधन देखें.

सैंपल

कोडलैब

ब्लॉग पोस्ट