Data Binding 浅析Ⅰ

Data Binding是一个support包,所以我们可以在Android2.1后的任意版本使用,使用前我们要确保项目的Gradle版本不低于1.5.0-alpha。

环境配置

首先下载Data Binding support Libraay,在我们model的build.gradle添加

dataBinging {
  enabled = true
}

如果你的工程有依赖的model,那么在依赖model的build.gradle文件中也需要加上上述代码。
同时我们还需要确保Android Studio的版本在1.3以上,才能够支持Data Binding。

Data Binding 布局文件

使用Data Binging框架的布局文件是用layout标签包裹着一个data 元素和一个view根元素,我们看下面这这个例子:

<?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_width="match_parent"       
    android:layout_height="match_parent">       

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

     <TextView android:layout_width="wrap_content"           
      android:layout_height="wrap_content"           
      android:text="@{user.lastName}"/>  
   </LinearLayout>
</layout>

variable="user"用来表示一个属性,用来在布局文件中使用,类似于java类中定义了一个user对象,类型是com.example.User这个类 在需要引用的地方使用"@{}"标签,例如给TextView赋值为User对象的firstName这个属性,代码如下

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

数据对象

假设我们有一个名字为User的java对象(POJO)

public class User {   
    public final String firstName;  
    public final String lastName;   

    public User(String firstName, String lastName) {      
       this.firstName = firstName;      
       this.lastName = lastName;   
    }
}

此类型的对象的属性值是不可以改变的,因此我们也可以使用javaBeans对象

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;  
 }
}

从数据绑定的角度来看,这两个类是等价的。 用于TextView的android:text属性的表达式@ {user.firstName}将访问前一类中的firstName字段和后一类中的getFirstName()方法。

Data Binding

默认情况下,将根据布局文件的名称生成一个Binding类,将其转换为Pascal大小写并在其后面加上“Binding”。 上面的布局文件是main_activity.xml,所以生成类是MainActivityBinding。 这个类保存从布局属性(例如用户变量)到布局视图的所有绑定,并知道如何为绑定表达式分配值。创建绑定的最简单的方法是在java类inflate布局文件时执行:

@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);
}

现在我们运行我们的程序,就可以看到User的信息显示在UI界面上了。
我们也可以通过:

  MainActivityBinding binding = MainActivityBinding.inflate(getLayoutInflater());

如果我们是在ListView或者是RecycleView的Adapter的布局文件中只要Data Binding,我们可以使用下面的方式进行绑定

ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false);
//或者是
ListItemBinding binding = DataBindingUtils.inflate(layoutInflate, R.layout.item_list, false);

事件处理

Data Binding允许我们在layout文件中编写绑定处理事件(例如OnClick)。事件属性的名称由监听器方法的名称来确定,但也有一些例外,比如View.OnLongClickListener有一个方法是onLongclik,所以这个时间的属性就是android:onLongClick。我们有两种方式来处理时间:

  • 1 方法引用
    我们在java类中创建事件的监听方法,而后在layout文件中导入该类,并引用其中的方法。
    例子如下:
    public class MyHandlers {
      public void onClickFriend(View view) { ... }
    

}

  为layout中的TextView绑定OnClick事件

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="handlers" type="com.example.Handlers"/>
<variable name="user" type="com.example.User"/>
</data>

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

   <TextView android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@{user.firstName}"
       android:onClick="@{handlers::onClickFriend}"/>

</LinearLayout>
</layout>

需要注意的是,我们引用的方法必须和OnClickListener方法的签名一致。
* 2监听器引用
  我们可以直接在layout文件使用lambda表达式编写处理逻辑,这种情况下,我们所引用的代码可以是任意业务逻辑代码。
例如:

public class Presenter {
public void onSaveClick(Task task){}
}

我们创建一个Presenter 这个类,有一个onSaveClick方法,用来点击后保存信息。

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="task" type="com.android.example.Task" />
<variable name="presenter" type="com.android.example.Presenter" />
</data>

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

      <Button
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:onClick="@{() -> presenter.onSaveClick(task)}" />
  </LinearLayout>

</layout>

上面的方法中我们没有定义传递的android.view.View参数,我们可以忽略所有的参数,也可以传递所有的参数,
所以我们还可以携程下面这个形式

android:onClick="@{(view) -> presenter.onSaveClick(view, task)}"

那么我们在Presenter中的方法就要定义成如下形式:

public void onSaveClick(View view, Task task){}

我们还可以用lambda表达式来表示多个参数

public class Presenter {
public void onCompletedChanged(Task task, boolean completed){}
}

<CheckBox android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onCheckedChanged="@{(cb, isChecked) -> presenter.completeChanged(task, isChecked)}" />

如果我们的事件有返回值,那么我们定义的放大的返回值需要和事件的返回值一致,例如

android:onLongClick="@{(view) -> presenter.onLongClick(view, task)}"

由于onLongClickListener的返回值是一个布尔值,那么我们定义的方法的返回值也必须是一个布尔值

public class Presenter {
public boolean onLongClick(View view, Task task){}
}

如果因为表达式的结果是null而不能实例化,Data Binding会返回该类型的默认值。例如:引用类型返回null,int类型返回0,布尔类型返回false,等等。
加入我们需要使用三元运算符,当结果为false时,不做任何操作,那么我们可以直接用void来代替。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容