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ể sử 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 trình bày cách tạo và tuỳ chỉnh các lớp liên kết được tạo.

Lớp liên kết được tạo liên kết biến bố cục với các chế độ xem trong của bạn. 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 sẽ được tạo cho từng 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 kiểu viết hoa Pascal thông qua thẻ Binding đã thêm hậu tố vào. Ví dụ: nếu tên tệp bố cục là activity_main.xml, lớp được tạo tương ứng là ActivityMainBinding. Lớp này lưu giữ tất cả các liên kết từ thuộc tính bố cục đến thuộc tính của bố cục khung hiển thị 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 tăng cường bố cục để tạo đảm bảo hệ phân cấp khung hiển thị 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 phương thức liên kết như 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() sẽ lấy ViewGroup ngoài đối tượng LayoutInflater , như 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 bố cục đó riêng biệt 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 kiểu 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 bạn đang sử dụng các mục liên kết dữ liệu bên trong một Fragment! ListView hoặc RecyclerView bộ chuyển đổi, bạn có thể muốn sử dụng inflate() của các lớp liên kết hoặc DataBindingUtil, vì như trong đoạn mã ví dụ 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 tạo một trường không thể thay đổi trong lớp liên kết cho mỗi thành phần 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 đây:

<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 chế độ xem (bao gồm cả mã nhận dạng) từ hệ phân cấp chế độ xem trong một lần. Cơ chế này có thể nhanh hơn việc gọi findViewById() cho mỗi thành phần hiển thị trong bố cục.

Mã nhận dạng không cần thiết như 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 chế độ xem từ mã.

Biến

Thư viện liên kết dữ liệu tạo 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 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ư chế độ xem thông thường, đối tượng ViewStub bắt đầu dưới dạng khung hiển thị vô hình. Khi chúng được hiển thị rõ ràng hoặc được tăng cường một cách rõ ràng, chúng 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 khung hiển thị trong đối tượng liên kết cũng phải biến mất để cho phép được xác nhận quyền sở hữu bằng cách thu gom rác. Vì quan điểm là cuối cùng, nên Đối tượng ViewStubProxy chiếm vị trí của ViewStub trong lớp liên kết được tạo, cung cấp cho bạn truy cập vào ViewStub khi nó tồn tại và truy cập vào thành phần hiển thị tăng cường khi ViewStub được tăng cường.

Khi tăng cườ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 nghe ViewStub OnInflateListener và thiết lập liên kết khi cần. Vì chỉ có thể tồn tại một trình nghe ở mỗi thời gian, ViewStubProxy cho phép bạn đặt OnInflateListener 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 được lên lịch để thay đổi trước khung tiếp theo. Tuy nhiên, có những trường hợp phải thực thi liên kết ngay lập tức. Để buộc thực thi, hãy sử dụng executePendingBindings() .

Biến động

Đôi khi, không xác định được lớp liên kết cụ thể. Ví dụ: một RecyclerView.Adapter hoạt động dựa trên bố cục tuỳ ý sẽ không biết lớp liên kết cụ thể. Nó phải gán giá trị liên kết trong suốt lệnh gọi đến onBindViewHolder() .

Trong ví dụ sau, tất cả bố cục mà RecyclerView liên kết để có một Biến item. Đối tượng BindingHolder có một phương thức getBinding() trả về 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 ở chế độ nền, miễn là đó không phải là bộ sưu tập. Liên kết dữ liệu sẽ bản địa hoá từng biến hoặc trường trong quá trình đánh giá thành để tránh mọi vấn đề đồng thời.

Tên lớp liên kết tuỳ chỉnh

Theo mặc định, 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, bỏ dấu gạch dưới ( _ ), viết hoa chữ cái đầu tiên chữ cái tiếp theo và thêm hậu tố là Binding. Ví dụ: tệp bố cục contact_item.xml tạo lớp ContactItemBinding. Lớp học đã được đặt trong gói databinding thuộc gói mô-đun. Ví dụ: nếu mô-đun gói là com.example.my.app, thì lớp liên kết này 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 tạo lớp liên kết ContactItem trong gói databinding trong 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 tiền tố vào lớp đó tên có dấu chấm. Ví dụ sau đây tạo ra 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 chứa lớp liên kết tạo. 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.