Liên kết thành phần hiển thị Một phần của Android Jetpack.

Liên kết thành phần hiển thị là một tính năng giúp bạn dễ dàng viết mã có hoạt động tương tác hơn có lượt xem. Sau khi bật tính năng liên kết thành phần hiển thị trong một mô-đun, mô-đun này sẽ tạo một liên kết class cho mỗi tệp bố cục XML có trong mô-đun đó. Một thực thể của liên kết chứa thông tin tham chiếu trực tiếp đến tất cả các chế độ xem có mã nhận dạng trong bố cục tương ứng.

Trong hầu hết các trường hợp, tính năng liên kết thành phần hiển thị sẽ thay thế findViewById.

Thiết lập

Tính năng liên kết khung hiển thị được bật trên cơ sở từng mô-đun. Để bật tính năng liên kết thành phần hiển thị trong một mô-đun, hãy đặt tuỳ chọn bản dựng viewBinding thành true ở cấp mô-đun build.gradle, như trong ví dụ sau:

Groovy

android {
    ...
    buildFeatures {
        viewBinding true
    }
}

Kotlin

android {
    ...
    buildFeatures {
        viewBinding = true
    }
}

Nếu bạn muốn bỏ qua tệp bố cục trong khi tạo lớp liên kết, hãy thêm thuộc tính tools:viewBindingIgnore="true" cho thành phần hiển thị gốc của bố cục đó tệp:

<LinearLayout
        ...
        tools:viewBindingIgnore="true" >
    ...
</LinearLayout>

Cách sử dụng

Nếu tính năng liên kết thành phần hiển thị được bật cho một mô-đun, thì hệ thống sẽ tạo một lớp liên kết cho mỗi mô-đun Tệp bố cục XML mà mô-đun chứa. Mỗi lớp liên kết chứa các tệp tham chiếu vào chế độ xem gốc và tất cả các chế độ xem có mã nhận dạng. Tên của lớp liên kết là được tạo bằng cách chuyển đổi tên của tệp XML theo quy ước viết hoa Pascal case và thêm từ "Binding" ở cuối.

Ví dụ: hãy xem xét một tệp bố cục có tên là result_profile.xml có chứa như sau:

<LinearLayout ... >
    <TextView android:id="@+id/name" />
    <ImageView android:cropToPadding="true" />
    <Button android:id="@+id/button"
        android:background="@drawable/rounded_button" />
</LinearLayout>

Lớp liên kết đã tạo có tên là ResultProfileBinding. Lớp này có hai các trường: một TextView có tên là name và một Button tên là button. Chiến lược phát hành đĩa đơn ImageView trong bố cục không có mã nhận dạng nên không có tham chiếu đến mã này trong lớp liên kết.

Mọi lớp liên kết đều bao gồm một phương thức getRoot(), phương thức này cung cấp một phương thức tham chiếu cho chế độ xem gốc của tệp bố cục tương ứng. Trong ví dụ này, phương thức getRoot() trong lớp ResultProfileBinding sẽ trả về Chế độ xem gốc LinearLayout.

Các phần sau đây minh hoạ cách sử dụng các lớp liên kết được tạo trong hoạt động và mảnh.

Sử dụng tính năng liên kết thành phần hiển thị trong các hoạt động

Để thiết lập một thực thể của lớp liên kết để sử dụng với một hoạt động, hãy thực hiện lệnh các bước sau trong Phương thức onCreate():

  1. Gọi phương thức inflate() tĩnh có trong lớp liên kết đã tạo. Thao tác này sẽ tạo một thực thể của lớp liên kết để hoạt động sử dụng.
  2. Lấy thông tin tham chiếu đến thành phần hiển thị gốc bằng cách gọi phương thức getRoot() hoặc sử dụng thuộc tính Kotlin .
  3. Truyền chế độ xem gốc vào setContentView() để chuyển sang chế độ xem đang kích hoạt trên màn hình.

Các bước này được thể hiện trong ví dụ sau đây:

Kotlin

private lateinit var binding: ResultProfileBinding

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ResultProfileBinding.inflate(layoutInflater)
    val view = binding.root
    setContentView(view)
}

Java

private ResultProfileBinding binding;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    binding = ResultProfileBinding.inflate(getLayoutInflater());
    View view = binding.getRoot();
    setContentView(view);
}

Bây giờ, bạn có thể sử dụng bản sao của lớp liên kết để tham chiếu bất kỳ khung hiển thị nào:

Kotlin

binding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }

Java

binding.name.setText(viewModel.getName());
binding.button.setOnClickListener(new View.OnClickListener() {
    viewModel.userClicked()
});

Sử dụng tính năng liên kết thành phần hiển thị trong các phân đoạn

Để thiết lập một thực thể của lớp liên kết để sử dụng với một mảnh, hãy thực hiện các bước sau trong phần onCreateView() phương thức:

  1. Gọi phương thức inflate() tĩnh có trong lớp liên kết đã tạo. Thao tác này sẽ tạo một thực thể của lớp liên kết để mảnh sử dụng.
  2. Lấy thông tin tham chiếu đến thành phần hiển thị gốc bằng cách gọi phương thức getRoot() hoặc sử dụng thuộc tính Kotlin .
  3. Trả về khung hiển thị gốc từ phương thức onCreateView() để đặt nó thành chế độ xem đang kích hoạt trên màn hình.

Kotlin

private var _binding: ResultProfileBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    _binding = ResultProfileBinding.inflate(inflater, container, false)
    val view = binding.root
    return view
}

override fun onDestroyView() {
    super.onDestroyView()
    _binding = null
}

Java

private ResultProfileBinding binding;

@Override
public View onCreateView (LayoutInflater inflater,
                          ViewGroup container,
                          Bundle savedInstanceState) {
    binding = ResultProfileBinding.inflate(inflater, container, false);
    View view = binding.getRoot();
    return view;
}

@Override
public void onDestroyView() {
    super.onDestroyView();
    binding = null;
}

Bây giờ, bạn có thể sử dụng bản sao của lớp liên kết để tham chiếu bất kỳ khung hiển thị nào:

Kotlin

binding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }

Java

binding.name.setText(viewModel.getName());
binding.button.setOnClickListener(new View.OnClickListener() {
    viewModel.userClicked()
});

Đưa ra gợi ý cho các cấu hình khác nhau

Khi bạn khai báo khung hiển thị trên nhiều cấu hình, đôi khi điều này khiến để sử dụng một kiểu khung hiển thị khác tuỳ thuộc vào bố cục cụ thể. Đoạn mã sau đây cho thấy một ví dụ về điều này:

# in res/layout/example.xml

<TextView android:id="@+id/user_bio" />

# in res/layout-land/example.xml

<EditText android:id="@+id/user_bio" />

Trong trường hợp này, lớp được tạo sẽ hiển thị trường userBio có kiểu TextView, vì TextView là lớp cơ sở chung. Do hạn chế về kỹ thuật, trình tạo mã liên kết khung hiển thị không thể xác định điều này và sẽ tạo một trường View. Bạn sẽ phải truyền trường vào lúc khác bằng binding.userBio as TextView.

Để khắc phục hạn chế này, tính năng liên kết thành phần hiển thị sẽ hỗ trợ tools:viewBindingType , cho phép bạn cho trình biên dịch biết nên sử dụng loại nào trong mã được tạo. Trong ví dụ trước, bạn có thể sử dụng thuộc tính này để làm cho trình biên dịch tạo trường dưới dạng TextView:

# in res/layout/example.xml (unchanged)

<TextView android:id="@+id/user_bio" />

# in res/layout-land/example.xml

<EditText android:id="@+id/user_bio" tools:viewBindingType="TextView" />

Trong một ví dụ khác, giả sử bạn có hai bố cục, một bố cục chứa BottomNavigationView và một mã khác chứa NavigationRailView. Cả hai các lớp mở rộng NavigationBarView, chứa hầu hết phương thức triển khai chi tiết. Nếu mã của bạn không cần biết chính xác lớp con nào có trong bố cục hiện tại, bạn có thể sử dụng tools:viewBindingType để đặt bố cục được tạo nhập vào NavigationBarView trong cả hai bố cục:

# in res/layout/navigation_example.xml

<BottomNavigationView android:id="@+id/navigation" tools:viewBindingType="NavigationBarView" />

# in res/layout-w720/navigation_example.xml

<NavigationRailView android:id="@+id/navigation" tools:viewBindingType="NavigationBarView" />

Tính năng liên kết khung hiển thị không thể xác thực giá trị của thuộc tính này khi tạo mã. Người nhận tránh các lỗi thời gian biên dịch và thời gian chạy, giá trị phải đáp ứng các yêu cầu sau điều kiện:

  • Giá trị phải là một lớp kế thừa từ android.view.View.
  • Giá trị phải là lớp cấp cao của thẻ mà giá trị đó được đặt trên đó. Ví dụ: các giá trị sau không hoạt động:

      <TextView tools:viewBindingType="ImageView" /> <!-- ImageView is not related to TextView. -->
      <TextView tools:viewBindingType="Button" /> <!-- Button is not a superclass of TextView. -->
    
  • Loại cuối cùng phải phân giải một cách nhất quán trên tất cả các cấu hình.

Điểm khác biệt với findViewById

So với việc sử dụng findViewById, tính năng liên kết khung hiển thị có những ưu điểm quan trọng:

  • An toàn với giá trị rỗng: vì tính năng liên kết khung hiển thị sẽ tạo thông tin tham chiếu trực tiếp đến khung hiển thị, không có nguy cơ xảy ra trường hợp ngoại lệ về con trỏ rỗng do mã khung hiển thị không hợp lệ. Ngoài ra, khi một khung hiển thị chỉ có trong một số cấu hình của bố cục, trường chứa tham chiếu của nó trong lớp liên kết sẽ được đánh dấu cùng với @Nullable.
  • An toàn về kiểu: các trường trong mỗi lớp liên kết có các kiểu khớp với các khung hiển thị chúng tham chiếu trong tệp XML. Điều này có nghĩa là sẽ không có rủi ro về một lớp ngoại lệ truyền.

Những khác biệt này có nghĩa là sự không tương thích giữa bố cục và mã của bạn khiến bản dựng gặp lỗi vào thời điểm biên dịch thay vì vào thời gian chạy.

So sánh với liên kết dữ liệu

Liên kết khung hiển thị và liên kết dữ liệu đều được tạo các lớp liên kết mà bạn có thể dùng để tham chiếu trực tiếp các khung hiển thị. Tuy nhiên, chế độ xem liên kết dùng để xử lý các trường hợp sử dụng đơn giản hơn và cung cấp những giá trị sau so với liên kết dữ liệu:

  • Biên dịch nhanh hơn: liên kết thành phần hiển thị không yêu cầu xử lý chú giải, vì vậy thời gian biên dịch nhanh hơn.
  • Dễ sử dụng: tính năng liên kết khung hiển thị không yêu cầu bố cục XML được gắn thẻ đặc biệt để áp dụng trong ứng dụng nhanh hơn. Sau khi bạn bật tính năng liên kết thành phần hiển thị trong một mô-đun, thì mô-đun đó sẽ tự động áp dụng cho tất cả bố cục của mô-đun đó.

Mặt khác, tính năng liên kết khung hiển thị có những hạn chế sau so với dữ liệu liên kết:

Do những cân nhắc này, trong một số trường hợp, tốt nhất bạn nên sử dụng cả hai chế độ xem liên kết dữ liệu và liên kết dữ liệu trong một dự án. Bạn có thể sử dụng liên kết dữ liệu trong các bố cục yêu cầu các tính năng nâng cao và sử dụng tính năng liên kết thành phần hiển thị trong những bố cục không yêu cầu các tính năng này.

Tài nguyên khác

Để tìm hiểu thêm về tính năng liên kết thành phần hiển thị, hãy xem thêm các tài nguyên sau:

Mẫu

Blog

Video