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()
:
- 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 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 . - 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:
- 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. - 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 . - 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:
- Tính năng liên kết khung hiển thị không hỗ trợ biến bố cục hoặc bố cục biểu thức nên không dùng được để khai báo nội dung giao diện người dùng động ngay từ các tệp bố cục XML.
- Tính năng liên kết khung hiển thị không hỗ trợ dữ liệu hai chiề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
Đề 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