ربط البيانات بين الطرفين

باستخدام ربط البيانات أحادي الاتجاه، يمكنك ضبط قيمة لسمة وضبط مستمع يتفاعل مع تغيير في هذه السمة:

<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()، تستخدم طريقة setter المقابلة للموقع تلقائيًا الاسم setRememberMe().

لمزيد من المعلومات عن استخدام BaseObservable و@Bindable، راجِع استخدام كائنات البيانات القابلة للتتبّع.

ربط البيانات ثنائية الاتجاه باستخدام السمات المخصّصة

توفِّر المنصّة عمليات تنفيذ ربط بيانات ثنائي الاتجاه للسمات الثنائية الاتجاه الأكثر شيوعًا وأدوات معالجة التغييرات، التي يمكنك استخدامها كجزء من تطبيقك. إذا أردت استخدام ربط البيانات الثنائي الاتجاه مع السمات المخصّصة، عليك استخدام التعليقات التوضيحية @InverseBindingAdapter و@InverseBindingMethod.

على سبيل المثال، إذا كنت تريد تفعيل ربط البيانات ثنائية الاتجاه لسمة "time" في طريقة عرض مخصّصة باسم MyView، أكمِل الخطوات التالية:

  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

مراجع إضافية

لمعرفة المزيد حول ربط البيانات، راجع الموارد الإضافية التالية.

عيّنات

الدروس التطبيقية حول الترميز

مشاركات المدونة