بااستفاده از اتصال داده یکطرفه، میتوانید مقداری را برای یک مشخصه تنظیم کنید و یک شنونده تنظیم کنید که به تغییر در آن مشخصه واکنش نشان دهد:
<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 فعال کنید، مراحل زیر را تکمیل کنید:
بااستفاده از
@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; } }
بااستفاده از
@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:selectedItemPositionandroid:selection |
AdapterViewBindingAdapter
|
CalendarView |
android:date |
CalendarViewBindingAdapter
|
CompoundButton |
android:checked
|
CompoundButtonBindingAdapter
|
DatePicker
|
android:yearandroid:monthandroid: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:hourandroid:minute |
TimePickerBindingAdapter
|
منابع بیشتر
برای کسب اطلاعات بیشتر درباره اتصال داده، به منابع اضافی زیر مراجعه کنید.
نمونهها
Codelabs
پستهای وبلاگ
توصیهشده برای شما
- توجه: وقتی جاوا اسکریپت خاموش باشد، نوشتار پیوند نمایش داده میشود
- کار کردن با اشیای دادههای دیدهشدنی
- چیدمانها و عبارتهای اتصال
- مقید کردن نماهای چیدمان به مؤلفههای معماری