Thư viện liên kết dữ liệu tạo các lớp liên kết mà bạn có thể dùng để truy cập vào các biến và khung hiển thị của bố cục. Tài liệu này cho biết cách tạo và tuỳ chỉnh các lớp liên kết đã tạo.
Lớp liên kết đã tạo sẽ liên kết các biến bố cục với các khung hiển thị trong bố cục. Bạn có thể tuỳ chỉnh tên và gói của liên kết. Tất cả các lớp liên kết được tạo đều kế thừa từ lớp ViewDataBinding
.
Một lớp liên kết được tạo cho mỗi tệp bố cục. Theo mặc định, tên của lớp là tên của tệp bố cục được chuyển đổi sang quy ước viết hoa Pascal case với hậu tố Binding được thêm vào. Ví dụ: nếu tên tệp bố cục là activity_main.xml
, thì lớp được tạo tương ứng sẽ là ActivityMainBinding
.
Lớp này lưu giữ mọi liên kết từ thuộc tính bố cục với chế độ xem của bố cục và biết cách gán giá trị cho biểu thức liên kết.
Tạo đối tượng liên kết
Đối tượng liên kết được tạo ngay sau khi mở rộng bố cục để đảm bảo hệ phân cấp khung hiển thị sẽ không bị sửa đổi trước khi liên kết với các khung hiển thị bằng biểu thức trong bố cục. Phương thức phổ biến nhất để liên kết đối tượng với một bố cục là sử dụng các phương thức tĩnh trên lớp liên kết. Bạn có thể tăng cường hệ phân cấp khung hiển thị và liên kết đối tượng với hệ phân cấp đó bằng cách sử dụng phương thức inflate()
của lớp liên kết, như minh hoạ trong ví dụ sau:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val binding: MyLayoutBinding = MyLayoutBinding.inflate(layoutInflater) setContentView(binding.root) }
Java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater()); setContentView(binding.root); }
Có một phiên bản thay thế của phương thức inflate()
lấy đối tượng ViewGroup
ngoài đối tượng LayoutInflater
, như trong ví dụ sau:
Kotlin
val binding: MyLayoutBinding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false)
Java
MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false);
Nếu bố cục được tăng cường bằng một cơ chế khác, bạn có thể liên kết riêng bố cục đó như sau:
Kotlin
val binding: MyLayoutBinding = MyLayoutBinding.bind(viewRoot)
Java
MyLayoutBinding binding = MyLayoutBinding.bind(viewRoot);
Đôi khi, bạn không biết trước loại liên kết. Trong những trường hợp như vậy, bạn có thể tạo liên kết bằng cách sử dụng lớp DataBindingUtil
, như minh hoạ trong đoạn mã sau:
Kotlin
val viewRoot = LayoutInflater.from(this).inflate(layoutId, parent, attachToParent) val binding: ViewDataBinding? = DataBindingUtil.bind(viewRoot)
Java
View viewRoot = LayoutInflater.from(this).inflate(layoutId, parent, attachToParent); ViewDataBinding binding = DataBindingUtil.bind(viewRoot);
Nếu đang sử dụng các mục liên kết dữ liệu bên trong bộ chuyển đổi Fragment
, ListView
hoặc RecyclerView
, bạn nên sử dụng phương thức inflate()
của các lớp liên kết hoặc lớp DataBindingUtil
, như minh hoạ trong ví dụ về mã sau:
Kotlin
val listItemBinding = ListItemBinding.inflate(layoutInflater, viewGroup, false) // or val listItemBinding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false)
Java
ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false); // or ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);
Chế độ xem có mã nhận dạng
Thư viện liên kết dữ liệu sẽ tạo một trường không thể thay đổi trong lớp liên kết cho mỗi khung hiển thị có một mã nhận dạng trong bố cục. Ví dụ: Thư viện liên kết dữ liệu tạo các trường firstName
và lastName
thuộc loại TextView
từ bố cục sau:
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="user" type="com.example.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.firstName}"
android:id="@+id/firstName"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.lastName}"
android:id="@+id/lastName"/>
</LinearLayout>
</layout>
Thư viện trích xuất các khung hiển thị (bao gồm cả mã nhận dạng) từ hệ phân cấp khung hiển thị chỉ trong một lần truyền. Cơ chế này có thể nhanh hơn việc gọi phương thức findViewById()
cho mọi khung hiển thị trong bố cục.
Mã nhận dạng không cần thiết vì khi không có liên kết dữ liệu, nhưng vẫn có một số trường hợp cần có quyền truy cập vào khung hiển thị từ mã.
Biến
Thư viện liên kết dữ liệu tạo các phương thức truy cập cho mỗi biến được khai báo trong bố cục. Ví dụ: bố cục sau đây tạo các phương thức setter và getter trong lớp liên kết cho các biến user
, image
và note
:
<data>
<import type="android.graphics.drawable.Drawable"/>
<variable name="user" type="com.example.User"/>
<variable name="image" type="Drawable"/>
<variable name="note" type="String"/>
</data>
ViewStub
Không giống như thành phần hiển thị thông thường, các đối tượng ViewStub
bắt đầu dưới dạng thành phần hiển thị ẩn. Khi được hiển thị hoặc tăng cường rõ ràng, chúng sẽ tự thay thế trong bố cục bằng cách tăng cường một bố cục khác.
Vì ViewStub
biến mất khỏi hệ phân cấp khung hiển thị, nên thành phần hiển thị trong đối tượng liên kết cũng phải biến mất để bộ thu gom rác có thể xác nhận quyền sở hữu đó.
Vì các khung hiển thị là cuối cùng nên đối tượng ViewStubProxy
sẽ chiếm vị trí của ViewStub
trong lớp liên kết được tạo, cho phép bạn truy cập vào ViewStub
khi đối tượng này tồn tại và quyền truy cập vào hệ phân cấp khung hiển thị tăng cường khi ViewStub
được tăng cường.
Khi mở rộng một bố cục khác, bạn phải thiết lập một liên kết cho bố cục mới đó.
Do đó, ViewStubProxy
phải theo dõi ViewStub
OnInflateListener
và thiết lập liên kết khi cần. Vì tại một thời điểm chỉ có một trình nghe có thể tồn tại, nên ViewStubProxy
cho phép bạn đặt một OnInflateListener
mà trình nghe này gọi sau khi thiết lập liên kết.
Liên kết ngay lập tức
Khi một biến hoặc đối tượng có thể quan sát thay đổi, liên kết sẽ được lên lịch để thay đổi trước khung tiếp theo. Tuy nhiên, có những trường hợp bạn phải thực thi liên kết ngay lập tức. Để buộc thực thi, hãy dùng phương thức executePendingBindings()
.
Biến động
Đôi khi, lớp liên kết cụ thể không xác định được. Ví dụ: RecyclerView.Adapter
hoạt động dựa trên bố cục tuỳ ý không biết lớp liên kết cụ thể. Hàm này phải gán giá trị liên kết trong khi gọi phương thức onBindViewHolder()
.
Trong ví dụ sau, tất cả các bố cục mà RecyclerView
liên kết để có một biến item
. Đối tượng BindingHolder
có phương thức getBinding()
trả về lớp cơ sở ViewDataBinding
.
Kotlin
override fun onBindViewHolder(holder: BindingHolder, position: Int) { item: T = items.get(position) holder.binding.setVariable(BR.item, item); holder.binding.executePendingBindings(); }
Java
public void onBindViewHolder(BindingHolder holder, int position) { final T item = items.get(position); holder.getBinding().setVariable(BR.item, item); holder.getBinding().executePendingBindings(); }
Luồng ở chế độ nền
Bạn có thể thay đổi mô hình dữ liệu trong một luồng trong nền, miễn là đó không phải là bộ sưu tập. Tính năng liên kết dữ liệu giúp bản địa hoá từng biến hoặc trường trong quá trình đánh giá để tránh mọi vấn đề đồng thời.
Tên lớp liên kết tùy chỉnh
Theo mặc định, một lớp liên kết được tạo dựa trên tên của tệp bố cục, bắt đầu bằng một chữ cái viết hoa, xoá dấu gạch dưới ( _ ), viết hoa chữ cái sau đây và thêm từ Binding vào phía sau. Ví dụ: tệp bố cục contact_item.xml
sẽ tạo lớp ContactItemBinding
. Lớp này được đặt trong gói databinding
trong gói mô-đun. Ví dụ: nếu gói mô-đun là com.example.my.app
, thì lớp liên kết sẽ được đặt trong gói com.example.my.app.databinding
.
Bạn có thể đổi tên hoặc đặt các lớp liên kết trong các gói khác nhau bằng cách điều chỉnh thuộc tính class
của phần tử data
. Ví dụ: bố cục sau đây sẽ tạo lớp liên kết ContactItem
trong gói databinding
của mô-đun hiện tại:
<data class="ContactItem">
...
</data>
Bạn có thể tạo lớp liên kết trong một gói khác bằng cách thêm một dấu chấm vào tiền tố tên lớp. Ví dụ sau đây sẽ tạo lớp liên kết trong gói mô-đun:
<data class=".ContactItem">
...
</data>
Bạn cũng có thể sử dụng tên gói đầy đủ mà bạn muốn tạo lớp liên kết. Ví dụ sau đây sẽ tạo lớp liên kết ContactItem
trong gói com.example
:
<data class="com.example.ContactItem">
...
</data>
Tài nguyên khác
Để tìm hiểu thêm về liên kết dữ liệu, hãy xem các tài nguyên bổ sung sau đây.
- Mẫu Thư viện liên kết dữ liệu Android
- Liên kết dữ liệu trong Android
- Liên kết dữ liệu — các bài học đã rút ra
Đề xuất cho bạn
- Lưu ý: văn bản có đường liên kết sẽ hiện khi JavaScript tắt
- Bố cục và biểu thức liên kết
- Thư viện liên kết dữ liệu
- Liên kết thành phần hiển thị