Khi viết ứng dụng android thì chắc hẳn chúng ta đều không xa lạ gì đến method findViewById. Khi mình mới làm quen với Android thì thấy việc này khá tẻ nhạt, khi số lượng view càng lớn thì số lượng những dòng findViewById sẽ càng tăng. Rất may có rất nhiều thư viện support để giảm bớt phần này, trước khi Kotlin ra đời chúng ta có thể xài 2 lib là butterknife và androidannotations. Sau đó thì mình chuyển qua code Kotlin thì việc xài kotlin-extensions để find view thật nhẹ nhàng bạn có thể access đến bất cứ các view thông qua id và không phải cast qua TextView hay Button.
Code Editor
Kotlin synthetics
Việc gọi theo view Id dẫn đến việc file source code của bạn sẽ không follow coding convention, các biến sẽ k upper case. Ngoài ra các bạn có thể gọi tới 1 view Id không reference tới layout hiện tại của Activity hay Fragment dẫn đến NullPointerException crash app. Hơn nữa kotlin extension chỉ hỗ trợ kotlin source, vậy với những file viết bằng Java thì sẽ xài ra sao?
Dựa trên những điều trên thì gần đây nếu project các bạn dùng kotlin-extension và kotlin-plugin mới nhất sẽ thấy được dòng warning sau khi build
The 'kotlin-android-extensions' Gradle plugin is deprecated.
Android studio recommend bạn xài View Binding plugin thay vì kotlin-extension plugin. Bạn chỉ nên xài kotlin-parcelize để giảm thời gian implement Parcelable object. Vậy hãy cùng bắt đầu tìm hiểu việc sử dụng View Binding nào.
Dựa trên những điều trên thì gần đây nếu project các bạn dùng kotlin-extension và kotlin-plugin mới nhất sẽ thấy được dòng warning sau khi build
The 'kotlin-android-extensions' Gradle plugin is deprecated.
Android studio recommend bạn xài View Binding plugin thay vì kotlin-extension plugin. Bạn chỉ nên xài kotlin-parcelize để giảm thời gian implement Parcelable object. Vậy hãy cùng bắt đầu tìm hiểu việc sử dụng View Binding nào.
I. Enable View Binding
Thêm buildFeatures vào từng build.gradle của module (app module, hoặc 1 số module của project của ứng dụng)
Sync and build project các bạn sẽ thấy nó generate ra các find ViewBinding. Ví dụ layout của bạn là fragment_home nó sẽ generate ra các file FragmentHomeBinding (implementation của ViewBinding interface). Các bạn có thể xem nội dung trong thư mục app/build/generated/data_binding_base_class_source_out
Lưu ý: Nếu các bạn muốn 1 số file layout không tự động generate thì các bạn có thể thêm tools:viewBindingIgnore="true" vào root view của layout.
Lưu ý: Nếu các bạn muốn 1 số file layout không tự động generate thì các bạn có thể thêm tools:viewBindingIgnore="true" vào root view của layout.
II. Các method ViewBinding support
inflate(@NonNull LayoutInflater inflater): Inflate layout của bạn mà không có parent view. thường được sử dụng khi inflate ViewBinding trong các Activity
inflate(@NonNull LayoutInflater inflater,@Nullable ViewGroup parent, boolean attachToParent): Inflate layout đi kèm với parent view thường được dùng tại Fragment hoặc RecycleView Holder, Custom View
bind(@NonNull View rootView): Method thường được dùng khi bạn đã inflate view ở đâu đó trong class. Ví dụ Fragment của bạn đã override onCreateView và đã inflate bằng layout id thì bạn có thể bind view đã được tạo trong onViewCreated
inflate(@NonNull LayoutInflater inflater,@Nullable ViewGroup parent, boolean attachToParent): Inflate layout đi kèm với parent view thường được dùng tại Fragment hoặc RecycleView Holder, Custom View
bind(@NonNull View rootView): Method thường được dùng khi bạn đã inflate view ở đâu đó trong class. Ví dụ Fragment của bạn đã override onCreateView và đã inflate bằng layout id thì bạn có thể bind view đã được tạo trong onViewCreated
III. Sử dụng
Fragment
ViewHolder
Activity
CustomView
IV. Các vấn đề sẽ gặp khi dùng ViewBinding
Khi Layout của bạn dùng <include/> tag và không dùng <merge> tag nếu bạn muốn access tới các view trong layout con bạn phải khai báo id cho chúng
Code Editor
Code Editor
Khi layout của bạn dùng <include/> và <merge> thì việc khai báo id và access tới view con qua id sẽ không work. ngay khi build time Android Studio sẽ thông báo không tìm thấy view id. Với trường hợp này bạn phải tự code để bind vào parent view
V. Tổng kết
Qua guideline vừa rồi thì chúng ta có thể thấy lợi ích của viewbinding được thể hiện qua null-safe, support cả Kotlin và Java và bạn chỉ có thể call các view trong Activity, Fragment.. của bạn thay vì kotlin synthetics call tất cả thông qua view id và chỉ crash khi runtime.
Ngoài ra thì xài viewbinding sẽ giảm đc memory so với kotlin synthetics, nếu bạn có decode file source kotlin sẽ thấy kotlin synthetics dùng HashMap (hoặc có thể config SparseArray) để cache view đã find nó sẽ tốn memory nhiều hơn một chút so với viewbinding
Note: 1 điểm hay của viewbinding khi layout của bạn có nhiều config (ví dụ config cho tablet..) nó sẽ null-safe những view không tồn tại ở tất cả các config sẽ được mark Nullable
Ngoài ra thì xài viewbinding sẽ giảm đc memory so với kotlin synthetics, nếu bạn có decode file source kotlin sẽ thấy kotlin synthetics dùng HashMap (hoặc có thể config SparseArray) để cache view đã find nó sẽ tốn memory nhiều hơn một chút so với viewbinding
Note: 1 điểm hay của viewbinding khi layout của bạn có nhiều config (ví dụ config cho tablet..) nó sẽ null-safe những view không tồn tại ở tất cả các config sẽ được mark Nullable
Reference: https://medium.com/androiddevelopers/use-view-binding-to-replace-findviewbyid-c83942471fc