اتصال داده دو طرفه

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

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

اتصال دو طرفه داده یک میانبر برای این فرآیند فراهم می کند:

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

نماد @={} ، که به طور مهمی شامل علامت "=" می‌شود، تغییرات داده‌ها را در ویژگی دریافت می‌کند و همزمان به به‌روزرسانی‌های کاربر گوش می‌دهد.

به منظور واکنش به تغییرات در داده‌های پشتیبان، می‌توانید متغیر layout خود را پیاده‌سازی 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);
        }
    }
}

از آنجایی که متد دریافت کننده ویژگی bindable 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. روشی را که مقدار را از view می خواند با استفاده از @InverseBindingAdapter حاشیه نویسی کنید:

    کاتلین

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

    جاوا

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

در این مرحله، داده binding می‌داند وقتی داده‌ها تغییر می‌کند چه کاری انجام دهد (روش مشروح‌شده با @BindingAdapter را فراخوانی می‌کند) و وقتی ویژگی view تغییر می‌کند چه چیزی را فراخوانی کند ( InverseBindingListener را فراخوانی می‌کند). با این حال، نمی داند این ویژگی کی و چگونه تغییر می کند.

برای این کار، باید یک شنونده را روی نما تنظیم کنید. این می تواند یک شنونده سفارشی مرتبط با نمای سفارشی شما باشد، یا می تواند یک رویداد عمومی باشد، مانند از دست دادن تمرکز یا تغییر متن. حاشیه نویسی @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 است، بنابراین باید با استفاده از مبدل فرمت شود.

از آنجایی که یک عبارت دو طرفه استفاده می شود، همچنین باید یک مبدل معکوس وجود داشته باشد تا به کتابخانه اطلاع دهد که چگونه رشته ارائه شده توسط کاربر را به نوع داده پشتیبان، در این مورد 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

پست های وبلاگ

{% کلمه به کلمه %} {% آخر کلمه %} {% کلمه به کلمه %} {% آخر کلمه %}