Liên kết khung hiển thị Một phần của Android Jetpack.
Liên kết khung hiển thị là một tính năng giúp bạn dễ dàng viết mã tương tác với khung hiển thị hơn. Sau khi bật tính năng liên kết khung hiển thị trong một mô-đun, mô-đun đó sẽ tạo một lớp liên kết cho từng tệp bố cục XML có trong mô-đun đó. Một thực thể của lớp liên kết có 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 theo từng mô-đun. Để bật tính năng liên kết khung hiển thị trong một mô-đun, hãy đặt tuỳ chọn bản dựng viewBinding
thành true
trong tệp build.gradle
cấp mô-đun, nh�� minh hoạ trong ví dụ sau:
Groovy
android { ... buildFeatures { viewBinding true } }
Kotlin
android { ... buildFeatures { viewBinding = true } }
Nếu bạn muốn bỏ qua một tệp bố cục trong khi tạo các lớp liên kết, hãy thêm thuộc tính tools:viewBindingIgnore="true"
vào khung hiển thị gốc của tệp bố cục đó:
<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, hệ thống sẽ tạo một lớp liên kết cho từng tệp bố cục XML có trong mô-đun đó. Mỗi lớp liên kết chứa thông tin tham chiếu đến khung hiển thị gốc và mọi khung hiển thị có mã nhận dạng. Tên của lớp liên kết đượ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" vào cuối.
Ví dụ: hãy xem xét tệp bố cục có tên là result_profile.xml
có chứa nội dung 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 được tạo có tên là ResultProfileBinding
. Lớp này có hai trường: một TextView
tên là name
và một Button
tên là button
. 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 cũng bao gồm một phương thức getRoot()
, cung cấp thông tin tham chiếu trực tiếp đến khung hiển thị 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ề khung hiển thị 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 các bước sau trong phương thức onCreate()
của hoạt động:
- 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. - Lấy thông tin tham chiếu đến khung hiển thị gốc bằng cách gọi phương thức
getRoot()
hoặc sử dụng cú pháp thuộc tính Kotlin. - Truyền khung hiển thị gốc vào
setContentView()
để đặt khung hiển thị đó làm khung hiển thị đang hoạt động 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); }
Giờ đây, bạn có thể sử dụng thực thể 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 mảnh
Để thiết lập một phiên bản 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ương thức onCreateView()
của mảnh:
- 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 phiên bản của lớp liên kết để mảnh sử dụng. - Lấy thông tin tham chiếu đến khung hiển thị gốc bằng cách gọi phương thức
getRoot()
hoặc sử dụng cú pháp thuộc tính Kotlin. - Trả về khung hiển thị gốc từ phương thức
onCreateView()
để đặt khung hiển thị đó làm khung hiển thị đang hoạt động 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; }
Giờ đây, bạn có thể sử dụng thực thể 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 khai báo các khung hiển thị trên nhiều cấu hình, đôi khi, bạn nên sử dụng một loại 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ụ:
# 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, bạn có thể muốn lớp được tạo hiển thị trường userBio
thuộc loại TextView
, vì TextView
là lớp cơ sở phổ biến. Do các 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 mà thay vào đó tạo ra trường View
. Để thực hiện thao tác này, bạn phải truyền trường này 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 khung hiển thị hỗ trợ thuộc tính tools:viewBindingType
, cho phép bạn cho trình biên dịch biết cầ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ó 2 bố cục, một bố cục chứa BottomNavigationView
và một bố cục khác chứa NavigationRailView
. Cả hai lớp đều mở rộng NavigationBarView
, trong đó chứa hầu hết thông tin triển khai. 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 loại đã tạo thành 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" />
Liên kết chế độ xem không thể xác thực giá trị của thuộc tính này khi tạo mã. Để tránh lỗi thời gian biên dịch và lỗi thời gian chạy, giá trị phải đáp ứng các điều kiện sau:
- 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ẻ được đặt. Ví dụ: các giá trị sau đây không có hiệu lực:
<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
Tính năng liên kết chế độ xem có những ưu điểm quan trọng so với việc sử dụng findViewById
:
- Xử lý an toàn giá trị rỗng: vì liên kết khung hiển thị tạo ra các tham chiếu trực tiếp đến các khung hiển thị, nên sẽ không có nguy cơ xảy ra 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ỉ xuất hiện trong một số cấu hình của bố cục, trường chứa tham chiếu của khung hiển thị đó trong lớp liên kết sẽ được đánh dấu bằng
@Nullable
. - An toàn về kiểu: các trường trong mỗi lớp liên kết có kiểu khớp với thành phần hiển thị mà các trường đó tham chiếu trong tệp XML. Điều này có nghĩa là không có nguy cơ xảy ra ngoại lệ truyền lớp.
Những khác biệt này đồng nghĩa với việc bố cục và mã của bạn không tương thích dẫn đến việc bản dựng không hoạt động được tại thời điểm biên dịch thay vì tại 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 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, tính năng liên kết khung hiển thị được thiết kế để xử lý các trường hợp sử dụng đơn giản hơn và mang lại những lợi ích sau so với liên kết dữ liệu:
- Biên dịch nhanh hơn: tính năng liên kết khung hiển thị không cần xử lý chú giải nên thời gian biên dịch sẽ 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 tệp bố cục XML được gắn thẻ chuyên biệt, nhờ đó, bạn sẽ có thể sử dụng nhanh chóng hơn trong ứng dụng. Sau khi bạn bật tính năng liên kết khung hiển thị trong một mô-đun, thao tác này 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ó các hạn chế sau đây so với liên kết dữ liệu:
- Tính năng liên kết khung hiển thị không hỗ trợ biến bố cục hoặc biểu thức bố cục. Vì vậy, bạn không thể dùng tính năng này để khai báo nội dung giao diện người dùng động ngay từ tệp bố cục XML.
- Tính năng liên kết khung hiển thị không hỗ trợ tính năng liên kết dữ liệu hai chiều.
Do những điểm cần cân nhắc này, trong một số trường hợp, bạn nên sử dụng cả tính năng liên kết khung hiển thị và liên kết dữ liệu trong một dự án. Bạn có thể dùng tính năng liên kết dữ liệu trong những bố cục yêu cầu các tính năng nâng cao và 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 như vậ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 các tài nguyên bổ sung sau đây:
Mẫu
Blog
Video
Đề xuất cho bạn
- Lưu ý: văn bản có đường liên kết sẽ hiện khi JavaScript tắt
- Di chuyển từ Kotlin Synthetics sang liên kết khung hiển thị Jetpack
- Bố cục và biểu thức liên kết
- Cấu trúc ứng dụng: Lớp giao diện người dùng – Bắt đầu – Nhà phát triển Android