+9

DATA BINDING TRONG ANDROID

Giới thiệu

Đến thời điểm này thì Databinding đang khá phổ biến và được sử dụng rộng rãi với nhưng tính năng ưu việt mà nó đem lại. Vậy nên hôm nay mình quyết định tìm hiểu và chia sẻ về Databinding cho mọi người cùng tham khảo. Databinding là một thư viện xuất hiện từ Android M. Nếu bạn đã chán ngấy việc findviewById() hay mong muốn có thể thực hiện code trên ngay file layout XML... Xin chúc mừng vì bạn đã có Databinding.

Cài đặt

Đầu tiên bạn phải chắc chắn rằng thiết bị của bạn sử dụng Adnroid SDK M trở lên , Android Studio >= 1.3 và Android Suppport Library > 15.0 (Nếu bạn không muốn sử dụng Maven thì download Android Support Library > 23).

Mở build.grade và thêm dataBinding { enabled = true } vào bên trong khối android{ // ...}

Ví dụ

Bây giờ cùng demo một project nhỏ để mọi người có thể dễ hiểu hơn về Binding dữ liệu nhé. Về cơ bản, thư viện này cho phép bạn để ràng buộc các giá trị của một đối tượng trực tiếp đến views trong layout, và nếu những thay đổi đối tượng, view sẽ được cập nhật tự động.

Đầu tiên mình sẽ tạo một đối tượng Account như sau :

public class Account {
    private String username, password;

    public Account(String username, String password) {
        this.username = username;
        this.password = password;
    }
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

Sau đó mình sẽ tạo thêm một layout với tên là demo.xml (Bạn hãy nhớ tên của layout nhé, về sau bạn sẽ cần đến nó)

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

    <data>

        <variable
            name="account"
            type="com.example.trantrungphong.demodatabinding.Account"/>
    </data>

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

        <TextView
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:gravity="center"
            android:text="@{account.username}"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:gravity="center"
            android:text="@{account.password}"/>
    </LinearLayout>
</layout>

Hãy để ý đến thẻ <data>...</data> với thể này nó tương đương vơi việc bạn đã khai báo việc hiển thị dữ liệu thông qua Databinding. AndroidStudio sẽ tự động sinh ra cho bạn một class <T>Binding để bạn sử dụng ngay và luôn. Bây giờ bạn cần sửa lại class Account một chút:

public class Account extends BaseObservable{
    private String username, password;

    public Account(String username, String password) {
        this.username = username;
        this.password = password;
    }

    @Bindable
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
        notifyPropertyChanged(BR.username);
    }

    @Bindable
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
        notifyPropertyChanged(BR.password);
    }
}

Hàm notifyPropertyChanged() thông báo cho các lớp được ràng buộc giá trị cụ thể này đã thay đổi và ràng buộc view hoặc cập nhật view cần thiết. Lớp BR đã tạo ra các ID được gắn với các fields trong đối tượng. Bất cứ điều gì được gắn kèm annotated @Bindable trong lớp mô hình sẽ có một ID trong lớp BR sẽ được sử dụng để thông báo. Điều này cho phép các lớp liên kết để cập nhật view Bây giờ bạn sang class MainActivity :

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DemoBinding binding = DataBindingUtil.setContentView(this, R.layout.demo);
        Account account = new Account("Demo", "Demo");
        binding.setAccount(account);
    }
}

Các bạn đã thấy chúng ta đã loại bỏ được khá nhiều dòng code nhàm chán Bạn có thể thêm vài dòng code :

        account.setUsername("PhongTT");
        account.setPassword("123456");

để thấy sự thay đổi Đối tượng DemoBinding sẽ được sinh ra theo tên layout mà bạn khai báo thẻ <data>, chính vì vậy mà mình đã lưu ý các bạn nên để ý đến tên layout ở phía trên. Phương thức binding.setAccount(account); dùng để update data lên layout. Account tương ứng với name mà bạn đã khai báo trong thẻ variable

Một ví dụ nữa cho các bạn hiểu thêm về Databinding nhé. Class Account :

public class Account extends BaseObservable{
    public ObservableField<String> username, password;

    public Account(String username, String password) {
        this.username.set(username);
        this.password.set(password);
    }
}

MainActivity

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DemoBinding binding = DataBindingUtil.setContentView(this, R.layout.demo);
        Account account = new Account("Demo", "Demo");
        binding.setAccount(account);
        account.username.set("PhongTT");
        account.password.set("123456");
    }
}

Với cách khai báo kiểu dữ liệu như trên bạn sẽ không phải quan tâm đên @Bindable hay hàm notifyPropertyChanged() nữa. vì chúng đã được định nghĩa sẵn đối với kiểu dữ liệu này rồi. Nó giúp cho code của bạn thêm gọn gàng hơn rất nhiều.

Trên là cách dùng Databinding với Activity, vậy còn với Fragment thì sao : Câu trả lời là nó cũng vô cùng đơn giản


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        FragmentFragBinding binding = DataBindingUtil.inflate(inflater,R.layout.fragment_frag1, container, false);
        View rootView = binding.getRoot();
        binding.setFragment1(new Text1("PhongTT"));
        return rootView;
    }

Tiếp tục là Databinding trong RecycleView : Ta tạo một class Texttt

public class Texttt {
    private String text;

    public Texttt(String text) {
        this.text = text;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }
}

Sau đó tạo layout databinding_recycleview_demo.xml

<?xml version="1.0" encoding="utf-8"?>
<layout>

    <data>

        <variable
            name="demorecyckedatabinding"
            type="com.example.trantrungphong.demodatabinding.Recycle.RecycleActivity"/>
    </data>

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycleview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </LinearLayout>
</layout>

Tiếp theo tạo một layout item_recycle.xml

<?xml version="1.0" encoding="utf-8"?>
<layout>
    <data>

        <variable
            name="itemview"
            type="com.example.trantrungphong.demodatabinding.Recycle.MyAdapter.MyViewHolder"/>
    </data>

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:orientation="vertical"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/colorPrimary"
            android:textSize="50dp"
            android:gravity="center"
            android:text="@{itemview.mText}"/>

    </LinearLayout>
</layout>

Tiếp theo tạo class MyAdapter.java

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>{

    private List<Texttt> mList = new ArrayList<>();

    public MyAdapter(List<Texttt> list) {
        mList = list;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        ItemRecycleBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext())
                , R.layout.item_recycle,parent, false);
        return new MyViewHolder(binding);
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        holder.setBinding(mList.get(position).getText());
    }

    @Override
    public int getItemCount() {
        return mList.size();
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        public ObservableField<String> mText = new ObservableField<>();
        public ItemRecycleBinding mBinding;

        public MyViewHolder(ItemRecycleBinding binding) {
            super(binding.getRoot());
            mBinding = binding;
        }

        public void setBinding(String text) {
            if (mBinding.getItemview() == null) mBinding.setItemview(this);
            mText.set(text);
        }
    }
}

Cuối cùng tạo class Activity để chạy chương trình:

public class RecycleActivity extends AppCompatActivity {
    private MyAdapter mAdapter;
    private DatabindingRecyleviewDemoBinding mBinding;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = DataBindingUtil.setContentView(this, R.layout.databinding_recyleview_demo);
        List<Texttt> texttts = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            texttts.add(new Texttt(i+""));
        }
        mAdapter = new MyAdapter(texttts);
        mBinding.recycleview.setLayoutManager(new LinearLayoutManager(this));
        mBinding.recycleview.setAdapter(mAdapter);
    }
}

Và kết quả là

Mình xin kết thúc phần này tại đây và sẽ tiếp tục tìm hiểu thêm về các tính năng khác và trình bày trong phần tiếp theo. Chúc mọi người làm việc hiệu quả.


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.