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根元素,我们看下面这这个例子:


  
         
        
     
         

            

       
   

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






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

   


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

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

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






  

      

上面的方法中我们没有定义传递的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){}
}

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来代替。

你可能感兴趣的