12/08/2018, 13:29

Tìm hiểu về Data Binding trong Android – Phần 1

Nhiều người chuyển từ . Net sang Android đều có một thắc mắc là trong android có Data Binding không? Rất may cho chúng ta là sau khi android M được ra đời thì Data Binding cũng được hỗ trợ. Và giờ chỉ cần định nghĩa nguồn dữ liệu, tự chúng sẽ hiển thị theo data tương ứng. Data Binding là ...

  • Nhiều người chuyển từ . Net sang Android đều có một thắc mắc là trong android có Data Binding không? Rất may cho chúng ta là sau khi android M được ra đời thì Data Binding cũng được hỗ trợ. Và giờ chỉ cần định nghĩa nguồn dữ liệu, tự chúng sẽ hiển thị theo data tương ứng.

Data Binding là gì?

  • Nếu bạn nào làm web rồi thì khái niệm này không gì xa lạ. Mình không muốn đưa ra định nghĩa ở đây. Mình sẽ đưa ra 1 ví dụ cụ thể cho các bạn dễ hiểu. Giả sử bạn có một TextView bạn muốn update dữ liệu lên nó thì bạn dùng findByViewId rồi setText cho nó giống như thế này:
        private TextView mName
        protected void onCreate(Bundle savedInstanceState) {
          setContentView(R.layout.activity_main);
          mName = (TextView) findViewById(R.id.name);
        }

        public void updateUI(User user) {
          if (user == null) {
            mName.setText(null);
          } else {
            mName.setText(user.getName());
          }
       }

Nhưng với Data Binding bạn chỉ cần:

       private ActivityMainBinding mBinding;
       protected void onCreate(Bundle savedInstanceState) {
              mBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
       }

       public void updateUI(User user) {
              mBinding.setUser(user);
       }
  • Và bây giờ bạn không cần phải quan tâm tới dữ liệu được đổ vào view nào nữa. Chúng ta có thể nói tạm biệt findByViewId. Còn rất nhiều cái hay ho nữa.

Ok. Bây giờ chúng ta bắt đầu vào việc thôi nhé.

Yêu cầu để có data binding

Android Plugin Gradle 1.5.0-alpha1 hoặc cao hơn .

Cấu hình môi trường

Để sử dụng data binding ta cần thêm thẻ trong file build.gradle

    android {
        ....
        dataBinding {
            enabled = true
        }
    }
  • Chúng ta đã hoàn thành trong phần cấu hình cho data binding.

  • Data Binding Layout Files

  • File xml của data binding trông nó như thế này

    <? 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_awidth = "match_parent"
           android:layout_height = "match_parent" >
           <TextView  android:layout_awidth = "wrap_content"
               android:layout_height = "wrap_content"
               android:text = "@{user.firstName}" />
           <TextView  android:layout_awidth = "wrap_content"
               android:layout_height = "wrap_content"
               android:text = "@{user.lastName}" />
       </LinearLayout>
    </layout>
  • Trong đó biến và dữ liệu được mô tả trong.
    <variable  name = "user"  type = "com.example.User" />

Các biểu thức thì được diểu diễn bằng ” @ {} “. Ở file trên là.

    <TextView android:layout_awidth = "wrap_content"
    android:layout_height = "wrap_content"
    android:text = "@{user.firstName}" />
  • File dữ liệu com.example.User trông như thế này .
    public class User {
       private final String firstName;
       private final String lastName;
       public User(String firstName, String lastName) {
           this.firstName = firstName;
           this.lastName = lastName;
       }
       public String getFirstName() {
           return this.firstName;
       }
       public String getLastName() {
           return this.lastName;
       }
    }
  • Bây giờ chỉ việc đổ dữ liệu thôi. Tại Activity (Giả sử của tôi là MainActivity) ta làm như sau:
    @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);
    }

Nhìn dòng

  MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);
  • Bạn sẽ tự hỏi class MainActivityBinding ở đâu. Xin thưa là nó được thằng Android tự generate ra theo file xml tương ứng.

  • Ví dụ ở trên file xml tên là “main_activity.xml” thì nó sẽ là MainActivityBinding. Giả sử bạn đặt tên file xml la hoc_sinh_activity thì file tương ứng là HocSinhActivityBinding.

  • Đó là cách bạn đổ dữ liệu lên activity. Còn đổ dữ liệu lên Fragment thì nó sẽ như thế này

    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    FragmentMainBinding binding = DataBindingUtil.inflate(inflater, R.layout.fragmnet_main, container, false);
            View view = binding.getRoot();
    //here data must be an instance of the class MarsDataProvider
    binding.setUser(new User("Tu hoc", "Android"));
    return view;
    }
  • Vậy tôi muốn đổ dữ liệu vào recylerview thì sao.

  • Đầu tiên bạn tạo một class viewholder tên là CustomViewHolder :

public class CustomViewHolder extends RecyclerView.ViewHolder {

  private ViewDataBinding mViewDataBinding;

    public CustomViewHolder(ViewDataBinding viewDataBinding) {
        super(viewDataBinding.getRoot());

        mViewDataBinding = viewDataBinding;
        mViewDataBinding.executePendingBindings();
    }

    public ViewDataBinding getViewDataBinding() {
        return mViewDataBinding;
    }
}
  • Còn class Adapter như sau:
    public class ExampleAdapter extends RecyclerView.Adapter<CustomViewHolder> {
        private List<User> mMyModels;

        public ExampleAdapter (List<User> myModels) {
            mMyModels = myModels;
        }

        @Override
        public CustomViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
            ViewDataBinding binding = DataBindingUtil.inflate(LayoutInflater.from(viewGroup.getContext()),
                    R.layout.item_user, viewGroup, false);

            return new CustomViewHolder(binding);
        }

        @Override
        public void onBindViewHolder(CustomViewHolder customViewHolder, int i) {
            ViewDataBinding viewDataBinding = customViewHolder.getViewDataBinding();

            viewDataBinding.setVariable(BR.user, mMyModels.get(i));
        }

        @Override
        public int getItemCount() {
            return (null != mMyModels ? mMyModels.size() : 0);
        }

    }

**Bạn để ý đến dòng

    viewDataBinding.setVariable(BR.user, mMyModels.get(i));
  • Cái BR.user ở đây chính là cái mà bạn khai báo biến trong file xml của item. ví dụ ở đây là
<data>
       <variable  name = "user"  type = "com.example.User" />
</data>
  • Việc còn lại bạn đổ dữ liệu như bình thường.
  ExampleAdapter adapter = new ExampleAdapter (userList);
  recylerview.setAdapter(adapter );
  • Mình xin kết thúc phần 1 ở đây. Trong phần 2 mình sẽ đi sâu hơn và cách binding dữ liệu theo ý muốn. Do viết bài nhanh nên hơi lủng củng. Nếu bạn không hiểu thì bạn có thể comment bên dưới. Rất mong các bạn ủng hộ. Cảm ơn các bạn đã đọc đến phần này.
0