1.介绍
DataBinding使数据跟布局变成了一种可能,是MVVM思想的一部分,免去了我们一直在findViewById然后设置等,这是它的优点,既然是学习它,缺点我就不说了,毕竟每个东西的出现都会有两面,我们只要在合适的地方使用就会避免掉它的缺点,从而彰显它的优点。
任何一个名字为aa_bc.xml布局只要是根节点标签是<layout>,只要这个布局被加载inflate,DataBinding工具都会帮我们生成一个相应的AaBcBinding,都是ViewDataBinding的子类,
可以通过DataBindingUtils.bind(view)或者DataBindingUtils.setContentView(actvity,View)或者其它方法得到。
一旦我们调用了DataBindingUtils.setContentView(actvity,View)这个方法或者是DataBindingUtils.bind(view)方法,加载的布局文件,使用布局文件的类,就会通过生成Binding相关联,binding可以直接通过布局中每个控件的id找到这个控件,然后做相关操作。
有时候我们自定义一个布局的时候,往往需要自定义自己的属性,这就需要导入:app标签,然后再style.xml<declare-stylable> </declare-stylable> 中声明自己的<attr/>,然后我们在自定义的布局的构造器中,用相应的方法得到自己设置的属性,然后设置给相应的控件,操作很繁琐吧,如果我们使用DataBinding就会非常简单,我们只需要导入:app标签然后直接声明属性给自己定义布局,比如app:tvName="String",然后我们在自定义布局中实现对应的setTvName(String str)方法就可以把str设置给我们想给的控件,是不是非常方便,从此不再需要写繁琐的<declaer-stylable>标签。
原理分析参考此文章,写的不错:http://www.jianshu.com/p/b1df61a4df77
2.构建
构建请参照github介绍https://github.com/XinRan5312/MasteringAndroidDataBinding
3.使用代码演示
如下是布局文件,如果使用Databinding最外层布局只能是layout另外还有data标签负责填写我们的数据定义和配置
<layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <!--用到什么类就要事先用import导包,就跟在类中写代码一样,比如下面我们用到Student和View类,所以 我们要首先导包,DataBinding用variable来定义变量 属性包裹变量名字和其类型,比如下面的stu和isQx变量 ,另外这里定义的变量就成为使用类的Binding类的变量,我们可以在使用类里通过binding.setXX来给他们赋值,比如 ActivityAsimpleBinding binding= DataBindingUtil.setContentView(this, R.layout.activity_asimple); Student stu=new Student(null,"Mack",18); binding.setStu(stu); binding.setIsQx(true); 从而达到使用类和对应布局数据的绑定 另外: 1,@{这里其实就是书写java代码的地方} 2,databinding语法中不但有?:三目运算,还有??两目预算@{stu.name??stu.firstName},如果 stu.name非null就是stu.name,否则就是stu.firstName --> <import type="com.xinran.qxdatabinding.beans.Student"></import> <import type="android.view.View"></import> <variable name="stu" type="Student"></variable> <variable name="isQx" type="boolean"></variable> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginLeft="20dp" android:layout_marginRight="20dp"> <TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="@{stu.name??stu.firstName}"/> <TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="成年" android:visibility="@{stu.age>18 ? View.VISIBLE : View.GONE}"/> <TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="上大学了" android:visibility="@{isQx ? View.VISIBLE : View.GONE}"/> </LinearLayout> </layout>
下面是使用布局的Activity的初始化代码,这是一个很简单使用例子
public class ASimpleActivity extends BaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ActivityAsimpleBinding binding= DataBindingUtil.setContentView(this, R.layout.activity_asimple); Student stu=new Student(null,"Mack",18); binding.setStu(stu); binding.setIsQx(true); } }
上面的例子是一个DataBinding自动生成Binding类,生成规则是布局名字根据驼峰,如果要自定义呢,也很简单只需要在data跟标签加class属性就好,代码如下:
<layout xmlns:android="http://schemas.android.com/apk/res/android"> <data class=".CustomBinding"> <variable name="name" type="String"></variable> <variable name="age" type="String"></variable> <!-- 我们自定义一个Binding的时候,就是不需要按照我们布局名字让DataBinding帮我们生成一个Binding时,我们 只需在data根标签添加class属性就好,用.开头后面跟自定义的类名字,比如 <data class=".CustomBinding"> 另外:定义的变量类型一定要和真实需要类型相同,否则DataBinding回报notFind异常,比如TextView的text需要的是 String类型的数据,如果我们非要把age变量定义成int类型,就会报错 --> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginLeft="20dp" android:layout_marginRight="20dp"> <TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="@{name}"/> <TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="@{age}" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="toChange" android:text="更改"/> </LinearLayout> </layout>
使用布局的类的代码:
public class CustomBindingActvity extends BaseActivity { private CustomBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding= DataBindingUtil.setContentView(this, R.layout.activity_custom); binding.setName("Join");