DataBinding基本使用包括以下内容: - 单纯的摆脱findviewbyid - 绑定基本数据类型及String - 绑定Model数据 - 绑定事件 - 通过静态方法转换数据类型 - 通过运算符操作数据 - 自定义Binding的类名 - 绑定相同Model的操作 - model变量改变自动更新数据 - 绑定List/Map等集合数据 - Observable自动更新 - Databinding与include标签的结合 - DataBinding与RecyclerView的结合
绑定相同model我的理解有2种,一种是同类的2个对象,另一种是不同类的2个类,但类名相同,具体看代码:
第一种,同一个类的2个对象,只需对象名不同就可以布局文件
<?xml version="1.0" encoding="utf-8"?><!--布局以layout作为根布局--> <layout> <data> <import type="www.zhang.com.databinding.User" /> <variable name="user3" type="User" /> <variable name="user4" type="User" /> </data> <!--我们需要展示的布局--> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="www.zhang.com.databinding.MainActivity"> <Button android:id="@+id/main_btn7" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@{user3.text}" /> <Button android:id="@+id/main_btn8" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@{user4.text}" /> </LinearLayout> </layout>User类
public class User { private String text; public User(String text) { this.text = text; } public String getText() { return text; } public void setText(String text) { this.text = text; } }MainActivity中
public class MainActivity extends AppCompatActivity { private ActivityMainBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //通过DataBInding加载布局都会对应的生成一个对象,如ActivityMainBinding,对象名在布局文件名称后加上了一个后缀Binding binding = DataBindingUtil.setContentView(MainActivity.this, R.layout.activity_main); User user3 = new User("相同类,不同对象1"); binding.setUser3(user3); User user4 = new User("相同类,不同对象2"); binding.setUser4(user4); } } 第二种不同的2个类,对象名相同布局文件
<?xml version="1.0" encoding="utf-8"?><!--布局以layout作为根布局--> <layout> <data> <import type="www.zhang.com.databinding.User" /> <variable name="user4" type="User" /> <!--因为type="User"都为User类,会导致不知道到那个包,所以可以通过alias属性重命名type的类型,但实际上alias被指定的那个类型(如:www.zhang.com.databinding.model.User)--> <import type="www.zhang.com.databinding.model.User" alias="Model"/> <variable name="user5" type="Model" /> </data> <!--我们需要展示的布局--> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="www.zhang.com.databinding.MainActivity"> <Button android:id="@+id/main_btn8" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@{user4.text}" /> <Button android:id="@+id/main_btn9" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@{user5.content}" /> </LinearLayout> </layout>因为2个地方都有type=”User”都为User类,会导致不知道导入哪个包,所以可以通过alias属性重命名type的类型,但实际上是alias被指定的那个类型(如:www.zhang.com.databinding.model.User)
2个不同的User类
package www.zhang.com.databinding; public class User { private String text; public User(String text) { this.text = text; } public String getText() { return text; } public void setText(String text) { this.text = text; } } package www.zhang.com.databinding.model; public class User { private String content; private boolean state; public User(String content, boolean state) { this.content = content; this.state = state; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public boolean isState() { return state; } public void setState(boolean state) { this.state = state; } }MainActivity
public class MainActivity extends AppCompatActivity { private ActivityMainBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //通过DataBInding加载布局都会对应的生成一个对象,如ActivityMainBinding,对象名在布局文件名称后加上了一个后缀Binding binding = DataBindingUtil.setContentView(MainActivity.this, R.layout.activity_main); User user4 = new User("相同类,不同对象2"); binding.setUser4(user4); www.zhang.com.databinding.model.User user5 = new www.zhang.com.databinding.model.User("类名相同,但不是相同的2个类",false); binding.setUser5(user5); } }前面讲了DataBinding对基本数据类型及Model的使用以及运算符等操作,但这些基本是静态的去设置数据,现在我们来看看 如何在数据改变时,不手动设置,让其自动改变。
布局文件
<?xml version="1.0" encoding="utf-8"?><!--布局以layout作为根布局--> <layout> <data> <import type="www.zhang.com.databinding.model.Person" /> <variable name="person" type="Person" /> </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="56dp" android:text="@{`firstName:`+person.firstName}" /> <TextView android:layout_width="match_parent" android:layout_height="56dp" android:text="@{`lastName:`+person.lastName}" /> <TextView android:layout_width="match_parent" android:layout_height="56dp" android:text="@{`age:`+person.age}" /> <Button android:id="@+id/second_btn1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="改变数据" /> </LinearLayout> </layout>Person类
package www.zhang.com.databinding.model; import android.databinding.BaseObservable; import android.databinding.Bindable; import www.zhang.com.databinding.BR; public class Person extends BaseObservable { private String firstName; private String lastName; private int age; public Person(String firstName, String lastName, int age) { this.firstName = firstName; this.lastName = lastName; this.age = age; } @Bindable public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; notifyPropertyChanged(BR.firstName); } @Bindable public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; notifyPropertyChanged(BR.lastName); } @Bindable public int getAge() { return age; } public void setAge(int age) { this.age = age; notifyPropertyChanged(BR.age); } }Model类继承BaseObservable,BaseObservable实现android.databinding.Observable接口,Observable接口可以允许附加一个监听器到model对象以便监听对象上的所有属性的变化。
Observable接口有一个机制来添加和删除监听器,但通知与否由开发人员管理。为了使开发更容易,BaseObservable实现了监听器注册机制。DataBinding实现类依然负责通知当属性改变时。这是通过指定一个Bindable注解给getter以及setter内通知来完成的。
notifyPropertyChanged(BR.参数名)通知更新这一个参数,需要与@Bindable注解配合使用。notifyChange()通知更新所有参数,可以不用和@Bindable注解配合使用
SecondActivity
public class SecondActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); ActivitySecondBinding binding = DataBindingUtil.setContentView(SecondActivity.this, R.layout.activity_second); final Person person = new Person("zhang","san",38); binding.setPerson(person); binding.secondBtn1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { person.setFirstName("li"); person.setLastName("si"); person.setAge(40); } }); } }