Khi sử dụng liên kết dữ liệu một chiều, bạn có thể đặt giá trị cho một thuộc tính và thiết lập trình nghe phản ứng với thay đổi trong thuộc tính đó:
<CheckBox android:id="@+id/rememberMeCheckBox" android:checked="@{viewmodel.rememberMe}" android:onCheckedChanged="@{viewmodel.rememberMeChanged}" />
Tính năng liên kết dữ liệu hai chiều cung cấp lối tắt đến quy trình này:
<CheckBox android:id="@+id/rememberMeCheckBox" android:checked="@={viewmodel.rememberMe}" />
Ký hiệu @={}
, quan trọng là bao gồm cả "=" ký, nhận dữ liệu
các thay đổi đối với thuộc tính và đồng thời theo dõi thông tin cập nhật của người dùng.
Để phản ứng với các thay đổi trong dữ liệu sao lưu, bạn có thể tạo bố cục
biến một cách triển khai Observable
, thường là
BaseObservable
và sử dụng
@Bindable
, như minh hoạ trong
đoạn mã sau:
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); } } }
Vì phương thức getter của thuộc tính có thể liên kết được gọi là getRememberMe()
, nên phương thức
phương thức setter tương ứng của thuộc tính sẽ tự động sử dụng tên
setRememberMe()
Để biết thêm thông tin về cách sử dụng BaseObservable
và @Bindable
, hãy xem bài viết Hợp tác với
đối tượng dữ liệu có thể ghi nhận được.
Liên kết dữ liệu hai chiều bằng thuộc tính tuỳ chỉnh
Nền tảng này cung cấp các cách triển khai liên kết dữ liệu hai chiều cho các phương pháp phổ biến nhất
thuộc tính hai chiều và thay đổi trình nghe mà bạn có thể dùng
như một phần của ứng dụng. Nếu bạn muốn sử dụng liên kết dữ liệu hai chiều bằng
bạn cần làm việc với
@InverseBindingAdapter
và
@InverseBindingMethod
các chú thích.
Ví dụ: nếu bạn muốn bật tính năng liên kết dữ liệu hai chiều trên thuộc tính "time"
trong khung hiển thị tuỳ chỉnh có tên là MyView
, hãy hoàn tất các bước sau:
Chú thích phương thức đặt giá trị ban đầu và cập nhật khi giá trị đó các thay đổi bằng cách sử dụng
@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; } }
Chú giải phương thức đọc giá trị trong khung hiển thị bằng cách sử dụng
@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(); }
Tại thời điểm này, liên kết dữ liệu biết việc cần làm khi dữ liệu thay đổi (nó gọi hàm
phương thức được chú thích bằng
@BindingAdapter
) và những việc cần làm
khi thuộc tính khung hiển thị thay đổi (phương thức này gọi phương thức
InverseBindingListener
).
Tuy nhiên, tài sản này không biết thuộc tính này thay đổi khi nào hoặc như thế nào.
Để làm được việc đó, bạn cần thiết lập trình nghe cho thành phần hiển thị (view). Đây có thể là một trình nghe tuỳ chỉnh
được liên kết với chế độ xem tuỳ chỉnh hoặc có thể là một sự kiện chung chung, chẳng hạn như mất mát
tiêu điểm hoặc thay đổi văn bản. Thêm chú giải @BindingAdapter
vào phương thức
để thiết lập trình nghe cho các thay đổi trên thuộc tính:
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. }
Trình nghe này bao gồm InverseBindingListener
dưới dạng tham số. Bạn sử dụng
InverseBindingListener
để cho hệ thống liên kết dữ liệu biết rằng thuộc tính này
đã thay đổi. Sau đó, hệ thống có thể bắt đầu gọi phương thức được chú giải bằng cách sử dụng
@InverseBindingAdapter
, v.v.
Trong thực tế, trình nghe này bao gồm một số logic không quan trọng, bao gồm cả trình nghe
để liên kết dữ liệu một chiều. Để biết ví dụ, hãy xem trình chuyển đổi cho thuộc tính văn bản
thay đổi,
TextViewBindingAdapter
.
Người chuyển đổi
Nếu biến được liên kết với đối tượng View
cần được định dạng, dịch hoặc thay đổi bằng cách nào đó trước khi được hiển thị,
bạn có thể sử dụng đối tượng Converter
.
Ví dụ: lấy đối tượng EditText
cho thấy ngày:
<EditText
android:id="@+id/birth_date"
android:text="@={Converter.dateToString(viewmodel.birthDate)}"
/>
Thuộc tính viewmodel.birthDate
chứa giá trị thuộc loại Long
nên cần
được định dạng bằng trình chuyển đổi.
Vì biểu thức hai chiều đang được sử dụng nên cũng cần phải có nghịch đảo
trình chuyển đổi để cho thư viện biết cách chuyển đổi lại chuỗi do người dùng cung cấp
kiểu dữ liệu sao lưu, trong trường hợp này là Long
. Quá trình này được thực hiện bằng cách thêm
chú giải @InverseMethod
cho một trong những trình chuyển đổi và có chú thích này tham chiếu giá trị nghịch đảo
bộ chuyển đổi. Ví dụ về cấu hình này xuất hiện trong mã sau
snippet:
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. } }
Vòng lặp vô hạn sử dụng liên kết dữ liệu hai chiều
Hãy cẩn thận để không tạo vòng lặp vô hạn khi sử dụng liên kết dữ liệu hai chiều. Thời gian
người dùng thay đổi một thuộc tính, thì phương thức được chú giải bằng cách sử dụng
@InverseBindingAdapter
được gọi và giá trị được gán cho phương thức sao lưu
thuộc tính này. Đổi lại, thao tác này sẽ gọi phương thức được chú giải bằng cách sử dụng
@BindingAdapter
, lệnh này sẽ kích hoạt một lệnh gọi khác đến phương thức được chú giải
bằng @InverseBindingAdapter
, v.v.
Vì lý do này, bạn cần phá vỡ các vòng lặp vô hạn có thể có bằng cách so sánh
các giá trị mới và cũ trong các phương thức được chú giải bằng @BindingAdapter
.
Thuộc tính hai chiều
Nền tảng này hỗ trợ tích hợp sẵn tính năng liên kết dữ liệu hai chiều khi bạn sử dụng các thuộc tính trong bảng sau. Để biết thông tin chi tiết về cách nền tảng cung cấp hỗ trợ này, hãy xem cách triển khai cho các bộ chuyển đổi liên kết tương ứng:
Lớp | (Các) thuộc tính | Bộ chuyển đổi liên kết |
---|---|---|
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
|
Tài nguyên khác
Để tìm hiểu thêm về liên kết dữ liệu, hãy tham khảo các tài nguyên khác.
Mẫu
Lớp học lập trình
Bài đăng trên blog
Đề xuất cho bạn
- Lưu ý: văn bản có đường liên kết sẽ hiện khi JavaScript tắt
- Làm việc với đối tượng dữ liệu có thể ghi nhận được
- Bố cục và biểu thức liên kết
- Liên kết khung hiển thị bố cục với thành phần cấu trúc