DataBinding的基本使用(三)
DataBinding基本使用包括以下内容:
- 单纯的摆脱findviewbyid
- 绑定基本数据类型及String
- 绑定Model数据
- 绑定事件
- 通过静态方法转换数据类型
- 通过运算符操作数据
- 自定义Binding的类名
- 绑定相同Model的操作
- model变量改变自动更新数据
- 绑定List/Map等集合数据
- Observable自动更新
- Databinding与include标签的结合
- DataBinding与RecyclerView的结合
3.8绑定相同model的操作
绑定相同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的使用以及运算符等操作,但这些基本是静态的去设置数据,现在我们来看看 如何在数据改变时,不手动设置,让其自动改变。
3.9model变量改变自动更新数据
布局文件
<?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);
}
});
}
}