12/08/2018, 13:01

Tìm Hiểu Data Binding Library - Part 2

Trong phần trước các bạn đã hiểu được cách thức triển khai cơ bản cho databinding (https://viblo.asia/tran.thanh.nghia/posts/lA7GKnnoMKZQ) Nhưng trước khi đi vào phần 2 này tôi xin cập nhật cách cấu hình môi trường mới được thay đổi trong Gradle (1.5.0-beta1 Chi tiết xem trong ...

Screen-Shot-2558-08-31-at-5.31.23-PM.jpg

Trong phần trước các bạn đã hiểu được cách thức triển khai cơ bản cho databinding (https://viblo.asia/tran.thanh.nghia/posts/lA7GKnnoMKZQ)

Nhưng trước khi đi vào phần 2 này tôi xin cập nhật cách cấu hình môi trường mới được thay đổi trong Gradle (1.5.0-beta1 Chi tiết xem trong http://tools.android.com/tech-docs/new-build-system )

alt

Và thêm đoạn code dưới đây

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

Và dưới đây alt

dependencies {
   classpath 'com.android.tools.build:gradle:1.5.0-beta1'
}

Trong phần 2 này tôi sẽ trình bày các kiến thức còn lại về Data Binding và kết hợp với các UI Control khác

Expression Language

Sau khi đọc qua part 1 thì ắt hẳn bạn sẽ thắc mắc rằng liệu có thể thực hiện các phép tính cơ bản như +, -, *, / ,... trên xml được không ?. Tôi xin trả lời có vì expression language của Data Binding có khá nhiều điểm giống với Java expression.

  • Toán học + - * /
  • Nối chuỗi +
  • Phép logic && ||
  • Phép nhị phân & | ^
  • Unary + - ! ~
  • Phép dịch bit >> >>> <<
  • Phép so sánh == != <= >=
  • instanceof
  • Gom nhóm ()
  • Cast
  • Gọi method
  • Truy cập field
  • Truy cập mảng
  • Toán tử ternary ?:

Ví dụ:

android:text="@{String.valueOf(index + 1)}"
android:visibility="@{age &lt ; 13 ? View.GONE : View.VISIBLE}"
android:transitionName='@{"image_" + id}'

&lt ; tương đương với <

Các toán tử còn thiếu

1 vài toán tử bị thiếu trong expression syntax. Bạn có thể sử dụng toán tử này trong code Java

  • this
  • super
  • new
  • Triền khai generic

Toán tử Null Coalescing

là toán tử (??) sẽ chọn toán hạng bên trái nếu nó khác null. Chọn bên phải đi toán hạng bằng null

 android:text="@{user.displayName ?? user.lastName}"

Nếu triển khai rõ ràng hơn thì như sau:

 android:text="@{user.displayName != null ? user.displayName : user.lastName}"

Binding nâng cao

Biến động

Đội khi các data binding class không biết cách triển khai Ví dụ RecyclerView.Adapter thì cách triển khai như sau

 public void onBindViewHolder(BindingHolder holder, int position) {
   final T item = mItems.get(position);
   holder.getBinding().setVariable(BR.item, item);
   holder.getBinding().executePendingBindings();
}

Immediate Binding (thực thi tức thì)

Khi biến thay đổi giá trị thì các Binding sẽ lập lịch để thay đổi trong frame tiếp theo. Tuy nhiên để bắt thực hiện ngay thì ta dùng executePendingBindings() để có thể update ngay data trên giao diện

Attribute Setters

Trong phần này tôi sẽ trình bày cách để custom attribute trong xml.

Automatic Setters

Đối với mỗi 1 attr thì Data Binding sẽ tìm method Setter của attribute đó. Phần namespace của attr không quan trọng, quan trọng là tên của attr

Ví dụ biểu thức binding được viết trong TextView's attribute android:text thì sẽ tìm setText(String) tương ứng. Nếu biểu thức trả về int thì data binding sẽ tìm method setText(int)

Trong đó:

      android là namespace

      text là tên attribute

Renamed Setters

Sẽ có lúc tên attribute có setter không trùng tên với nhau. Với trường hợp này bạn cần chỉ định rõ attribute đó tương ứng với method setter nào

Ví dụ: có attr android:tint có setter tương ứng là setImageTintList(ColorStateList) nhưng nếu bạn không chỉ định rõ setter thì data binding sẽ tự động tìm tới setTint (setTint - không tồn tại)

Lúc này bạn cần code như sau:

 @BindingMethods({
       @BindingMethod(type = "android.widget.ImageView",
                      attribute = "android:tint",
                      method = "setImageTintList"),
})

Custom Setters

Data Binding cung cấp custom attribute (BindingAdapter) trong trường hợp bạn cần custom lại logic của attribute đó

Ví dụ ImageView bạn cần load image từ 1 url nào đó trên mạng

 @BindingAdapter({"bind:imageUrl", "bind:error"})
public static void loadImage(ImageView view, String url, Drawable error) {
   Picasso.with(view.getContext()).load(url).error(error).into(view);
}

Data Binding cho phép nhận nhiều parameter

Khai báo trong xml:

 <ImageView app:imageUrl=“@{venue.imageUrl}”
app:error=“@{@drawable/venueError}”/>

Như bạn đã thấy nó khá dễ dàng cho việc sử dụng các Library khác để implement vào trong project của bạn

Việc triển khai code khá đơn giản

Trong RecyclerViewAdapter

 public static class BindingHolder extends RecyclerView.ViewHolder {
        private ViewDataBinding binding;

        public BindingHolder(View v) {
            super(v);
            binding = DataBindingUtil.bind(v);
        }

        public ViewDataBinding getBinding() {
            return binding;
        }
    }
 @Override
    public void onBindViewHolder(BindingHolder holder, int position) {
        final User user = mList.get(position);
        holder.getBinding().setVariable(BR.user, user);
        holder.getBinding().setVariable(BR.index,position+"");
        holder.getBinding().executePendingBindings();
    }

Khai báo trong item_recycler_view.xml

 <?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

        <variable
            name="index"
            type="String"/>

        <variable
            name="user"
            type="com.nghiatt.demobinding.model.User"
            />
    </data>

    <LinearLayout
        android:layout_awidth="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:layout_awidth="wrap_content"
            android:layout_height="wrap_content"
            app:text="@{index}"
            />
        <TextView
            android:text="@{user.name}"
            android:layout_awidth="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>
</layout>

Custom Attribute text của TextView app:text="@{index}

 @BindingAdapter("text")
    public static void setText(TextView textView, String text) {
        textView.setText("custom attr item " + text);
    }

device-2015-11-27-104919.png

Cuối bài tôi xin gửi demo cho việc kết hợp Data Binding với RecyclerView tại **đây GitHub ** (https://github.com/NghiaTran92/DemoDataBinding/tree/data_binding_part_2) device-2015-11-27-001511.png

Cảm nhận mỗi người là khác nhau. Vậy nên tôi khuyên bạn hãy sắn tay áo lên và hãy bắt đầu code vài sample của mình về Data Binding Library. Lúc đó bạn sẽ cảm nhận được những điều tuyệt vời mà Data Binding mang lại

  • http://developer.android.com/intl/vi/tools/data-binding/guide.html
0