Tìm hiểu về data binding trong android

Data binding là một thự viện được google giới thiệu trong thời gian gần đây mà theo như những gì mà google đã giới thiệu thì nó sẽ giúp cho các lập trình viên Android có thể viết code ngắn gọn hơn và dễ hiểu hơn. Trong bài viết này mình sẽ cùng các bạn tìm hiểu về data binding và các trường hợp có thể áp dụng nó trong khi phát triển ứng dụng android.

Cài đặt môi trường

Để sử dụng data binding chúng ta cần sử dụng phiên bản android studio 1.3 trở lên và enable nó trong file gradle.setting trong app module

android {
    ....
    dataBinding {
        enabled = true
    }
}

Nếu trong app module có phụ thuộc vào một thư viện sử dụng data binding thì trong app module cũng cần cấu hình như trên.

Sử dụng data binding trong dự án

  • File layout Khi sử dụng data binding file layout sẽ khác so với file layout thông thường mà chúng ta thường thấy nó bắt đầu bằng thẻ layout và tiếp theo là thẻ dataview root.
<?xml version="1.0" encoding="utf-8"?>
<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}"/>
       <TextView android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{user.lastName}"/>
   </LinearLayout>
</layout

Thẻ variable định nghĩa một thuộc tính sẽ sử dụng trong file layout

Mặc định data binding sẽ tạo ra một class là một lớp con của ViewDataBinding

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);
   User user = new User("Test", "User");
   binding.setUser(user);
}

Custom Attributes (Binding Adapters)

Nhiều lập trình viên chỉ sử dụng data binding để thay cho câu lệnh findViewById() nhưng trên thực tế chúng ta có thể sử dụng data binding trong rất nhiều trường hợp như có thể custom atrributes sử dụng Binding Adapters

  • Chúng ta thêm một thuộc tính "app:imageUrl" cho ImageView
@BindingAdapter({"app:imageUrl", "app:error"})
public static void loadImage(ImageView view, String url, Drawable error {
    Glide.with(view.getContext())
        .load(url)
        .error(error)
        .into(view);
}
  • Custom font
@BindingAdapter({"app:font"})
public static void setFont(TextView textView, String fontName) {
    textView
        .setTypeface(FontCache.getInstance(context)
        .get(fontName));
}
  • Thêm animation khi hiển thị View
@BindingAdapter({"app:animatedVisibility"})
    public static void setVisibility(View view, int visibility) {
        …
        ObjectAnimator alpha = ObjectAnimator.ofFloat(view, View.ALPHA, startAlpha, endAlpha);
    …
    alpha.start();
}

Event Handlers

Chúng ta có thể sử dụng data binding để handle những sự kiện mà người dùng tương tác với view

public class UserViewModel {
    …
    public View.OnClickListener clickListener;
    …
}
<View
android:onClick="@{viewModel.clickListener}"
… />

String formatting

Format một String ngay trong file layout

<resources>
    <string name="greeting">Hello, %s</string>
</resources>

<TextView
    android:text="@{@string/greeting(user.firstName)}"/>

Overriding Android attributes

Ngoaì việc định nghĩa thêm các thuộc tính cho View chúng ta cũng có thể custom lại những thuộc tính đã có sẵn

@BindingAdapter("android:layout_margin")
    public static void setMargin(View view, float margin) {
        MarginLayoutParams lp = (MarginLayoutParams)
        view.getLayoutParams();
        lp.setMargins(margin, margin, margin, margin);
        view.setLayoutParams(layoutParams);
    }