ترابست داده‌های دوسویه

بااستفاده از اتصال داده یک‌طرفه، می‌توانید مقداری را برای یک مشخصه تنظیم کنید و یک شنونده تنظیم کنید که به تغییر در آن مشخصه واکنش نشان دهد:

<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 استفاده کنید، همان‌طور که در قطعه کد زیر نشان داده شده است:

کاتلین

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)
        }
    }
}

جاوا

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 کار کنید.

برای مثال، اگر می‌خواهید اتصال داده دوطرفه را در ویژگی "time" در نمای سفارشی‌ای به‌نام MyView فعال کنید، مراحل زیر را تکمیل کنید:

  1. بااستفاده از @BindingAdapter، روشی را که مقدار اولیه را تنظیم می‌کند و هنگام تغییر مقدار به‌روز می‌شود حاشیه‌نویسی کنید:

    کاتلین

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

    جاوا

    @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، روشی را که مقدار را از نما می‌خواند حاشیه‌نویسی کنید:

    کاتلین

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

    جاوا

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

At this point, data binding knows what to do when the data changes (it calls the method annotated with @BindingAdapter) and what to call when the view attribute changes (it calls the InverseBindingListener). However, it doesn't know when or how the attribute changes.

برای این کار، باید شنونده‌ای را در نما تنظیم کنید. این رویداد می‌تواند یک شنونده سفارشی مرتبط با نمای سفارشی شما باشد، یا می‌تواند یک رویداد عمومی باشد، مانند ازدست دادن تمرکز یا تغییر متن. حاشیه‌نویسی @BindingAdapter را به روشی اضافه کنید که شنونده را برای تغییرات در ویژگی تنظیم می‌کند:

کاتلین

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

جاوا

@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 است، بنابراین باید بااستفاده از مبدل قالب‌بندی شود.

Because a two-way expression is being used, there also needs to be an inverse converter to let the library know how to convert the user-provided string back to the backing data type, in this case Long. این فرایند با افزودن حاشیه‌نویسی @InverseMethod به یکی از مبدل‌ها و ارجاع این حاشیه‌نویسی به مبدل معکوس انجام می‌شود. نمونه‌ای از این پیکربندی در تکه‌کد زیر نشان داده شده است:

کاتلین

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.
    }
}

جاوا

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

منابع بیشتر

برای کسب اطلاعات بیشتر درباره اتصال داده، به منابع اضافی زیر مراجعه کنید.

نمونه‌ها

Codelabs

پست‌های وبلاگ