AAC---DataBinding使用

2018-10-24 14:42:58 浏览数 (1)

DataBinding介绍

DataBinding类似于ButterKnife,可以将数据结构与XML绑定,节省了很多Activity中UI的代码,比如说findViewById等。也可以提升APP性能,帮助避免内存泄露以及空指针的问题。

DataBinding的使用

  1. app模块的build.gradle中添加DataBinding配置:
代码语言:javascript复制
android {
    ...
    dataBinding {
        enabled = true
    }
}
  1. 定义XML对应的数据结构
代码语言:javascript复制
package com.example.aactest;

public class Data {
    private String name;
    private String title;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}
  1. 创建layout.xml文件(如activity_main.xml): 与原来的XML文件不同的是,根节点的为layout,而不是具体的ViewGroup。并且将与该xml绑定的数据需要在data标签中定义,并且在下方的View中将属性与子View绑定。
代码语言:javascript复制
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <data>
        <import type="com.example.aactest.Data" />
        <variable
            name="aacdata"
            type="com.example.aactest.Data" />
    </data>

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{aacdata.title}" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{aacdata.name}" />
    </android.support.constraint.ConstraintLayout>
</layout>
  1. 编译完成后,在/app/build/generated/source/apt/debug下会新增一个packagename.databinding的文件夹,并且根据layout.xml编译生成的文件,而该文件名就是xml对应的名称。

比如:包名为com.example.aactest的应用,在上述目录下会生成com.example.aactest.databinding的文件夹,而activity_main.xml就会生成ActivityMainBinding.java文件

  1. 使用DataBinding绑定具体数据 在生成的ActivityMainBinding文件中,就会有数据部分的setget方法,在调用完set方法更新完Binding中的数据后,对应的View也会更新。
代码语言:javascript复制
public class MainActivity extends AppCompatActivity {
    ActivityMainBinding mBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        final Data data=new Data();
        data.setTitle("This is Title");
        data.setName("This is User Name");
        mBinding.setTd(data);
        Handler handler = new Handler(new Handler.Callback() {
            @Override public boolean handleMessage(Message message) {
                data.setTitle("Change Title");
                mBinding.setTd(data);
                return false;
            }
        });
        handler.sendEmptyMessageDelayed(1, 5000L);
    }
}

DataBinding在RecyclerView中的使用

同在RecyclerView中的Item也可以使用DataBinding,在onCreateViewHolder中保存生成的Binding对象,在复用时,更新数据即可。并且可以在XML中设置ClickListener等事件。

RecyclerView的product_item.xml文件如下:

代码语言:javascript复制
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>
        <variable name="product"
                  type="com.example.android.persistence.model.Product"/>
        <variable name="callback"
                  type="com.example.android.persistence.ui.ProductClickCallback"/>
    </data>

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="@dimen/product_item_min_height"
        android:onClick="@{() ->  callback.onClick(product)}"
        android:orientation="horizontal"
        android:layout_marginStart="@dimen/item_horizontal_margin"
        android:layout_marginEnd="@dimen/item_horizontal_margin"
        app:cardUseCompatPadding="true">

            <TextView
                android:id="@ id/name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:contentDescription="@string/cd_product_name"
                android:text="@{product.name}"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentEnd="true"
                android:layout_marginEnd="5dp"
                android:text="@{@string/product_price(product.price)}"/>

    </android.support.v7.widget.CardView>
</layout>

RecyclerAdapter中部分内容如下:

代码语言:javascript复制
    @Override
    public ProductViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        ProductItemBinding binding = DataBindingUtil
                .inflate(LayoutInflater.from(parent.getContext()), R.layout.product_item,
                        parent, false);
        binding.setCallback(mProductClickCallback);
        return new ProductViewHolder(binding);
    }

    @Override
    public void onBindViewHolder(ProductViewHolder holder, int position) {
        holder.binding.setProduct(mProductList.get(position));
        holder.binding.executePendingBindings();
    }

    static class ProductViewHolder extends RecyclerView.ViewHolder {

        final ProductItemBinding binding;

        public ProductViewHolder(ProductItemBinding binding) {
            super(binding.getRoot());
            this.binding = binding;
        }
    }    

PS:在使用RecyclerView的时候,经常配合DiffUtil来进行数据的增量更新操作

注意事项

  • 在使用数据的时候,属性必须是public或者提供了settergetter方法,否则编译不过,无法生成Binding文件
  • XML文件中禁止使用merge标签,可以使用include标签,但是需要将变量传过去,否则数据无法传递。例如:
代码语言:javascript复制
product_fragment.xml
...
<include
            layout="@layout/product_item"
            app:product="@{productViewModel.product}"/>
...

product_item.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>
        <variable name="product"
                  type="com.example.android.persistence.model.Product"/>
        <variable name="callback"
                  type="com.example.android.persistence.ui.ProductClickCallback"/>
    </data>
...

参考链接

Data Binding Library DataBinding最全使用说明

0 人点赞