Lớp liên kết được tạo

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 firstNamelastName 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, imagenote:

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

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.